【问题标题】:QWidget resize signal?QWidget调整大小信号?
【发布时间】:2012-02-15 20:48:06
【问题描述】:

我想在小部件调整大小时采取行动。

有没有办法在没有在该小部件上安装事件过滤器的情况下捕获它(显然,没有子类化它)? AFAIK,QWidget 没有resized 信号。

【问题讨论】:

  • 不,你不能。 bset 方法是:创建你自己的 QWidget,它在 resizeEvent() 中发出 Resized,然后将你的小部件提升到它:)

标签: qt qt4 pyqt pyqt4


【解决方案1】:

您可以从widget 类派生并重新实现resizeEvent 事件

【讨论】:

  • 请注意,warwaruk 写道“而且,显然,没有子类化它”
  • @KamilKlimek, ...在我发布答案后:)
  • 我不会删除答案,我认为这可能对可以搜索此问题的人有用
  • 我没有告诉任何关于删除你的答案的事情
【解决方案2】:

如果您有任何其他可以与该 QWidget 有严格关系的 QObject,您可以使用 QObject::installEventFilter(QObject * filter) 并重载 bool eventFilter(QObject *, QEvent *)。更多信息请访问Qt docs

【讨论】:

    【解决方案3】:

    如果您将 Python 与 PyQt4 一起使用,您可以将 widget.resizeEvent 设置为您的函数,而无需对其进行子类化:

    #!/usr/bin/env python
    import sys
    from PyQt4 import QtCore, QtGui
    
    def onResize(event):
        print event
    
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        widget = QtGui.QPushButton('Test')
        widget.resizeEvent = onResize
        widget.resize(640, 480)
        widget.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • 这会阻止 resizeEvent 的基类实现运行。它可能正在做一些重要的事情。使用猴子补丁解决方案,您必须将对原始方法的引用保留为单独的变量。凌乱。
    • @Chris 文档说,在调用 resizeEvent 时,小部件已经有了新的几何形状,所以如果您在主小部件上没有其他事情要做,您可以覆盖该功能。我使用这种技术来调整 QScrollArea 的内容。
    【解决方案4】:

    对不起,它看起来像一个 hack,但我用这个:

        some_widget.resizeEvent = (lambda old_method: (lambda event: (self._on_resized(event), old_method(event))[-1]))(some_widget.resizeEvent)
    

    【讨论】:

    • 为了易读性而设计的 Python 就这么多。但是,+1 用于保留超级实现。
    • 谢谢你,斯宾塞!这里的每个答案都忘记在做完他的事情后重新调用以前的回调。
    【解决方案5】:

    这已经晚了几年,但我正在开发一个可以完全覆盖父级的透明覆盖小部件。没有子类化你不能做你想做的事,但是你可以像@reclosedev 建议的那样将子类化限制为一个实例,这意味着你不必实际创建一个子类。

    我编写了以下 sn-p(在 PyQt4 中工作)来跟踪添加小部件的任何小部件的大小:

    class TransparentOverlay(QtGui.QWidget):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.setAttribute(QtCore.Qt.WA_NoSystemBackground)
            self._updateParent(self.parentWidget())
    
        def setParent(self, parent, *args):
            prevParent = self.parentWidget()
            super().setParent(parent, *args)
            self._updateParent(parent, prevParent)
    
        def unsetParent(self, parent=None):
            if parent is None:
                parent = self.parentWidget()
            if parent is not None and hasattr(parent.resizeEvent, '_original'):
                parent.resizeEvent = parent.resizeEvent._original
    
        def _updateParent(self, parent, prevParent=None):
            if parent is not prevParent:
                self.unsetParent(prevParent)
                if parent is not None:
                    original = parent.resizeEvent
                    def resizeEventWrapper(event):
                        original(event)
                        self.resize(event.size())
                    resizeEventWrapper._original = original
                    parent.resizeEvent = resizeEventWrapper
                    self.resize(parent.size())
    

    这段代码使用了一些 Python 可以使用的巧妙技巧:

    • 原始方法隐藏在新方法的_original 属性中。这是可能的,因为函数是对象。
    • 新方法真正继承了任何QWidget instance,这意味着您不必创建实际的子类。借助附加的方法,每个父实例都将有效地成为子类的实例。

    如果您需要一次性的东西,所有用于删除子类resizeEvent 方法并将其替换为原始方法的代码都可以丢弃。在这种情况下,该解决方案基本上是 @reclosedev 解决方案的更高级版本,但 @Chris 的 cmets 关于保留原始地址。

    此代码的唯一警告是它不能正确支持 GL 小部件,因此例如不能始终将叠加层添加到 QGraphicsView 的视口中。但是,它可以添加到 QGraphicsView 本身。

    【讨论】:

      【解决方案6】:

      您可以通过

      覆盖resizeEvent
      def resizeEvent(self, newSize):
          #do code here
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-11-23
        • 2017-11-02
        • 1970-01-01
        • 2014-01-17
        • 1970-01-01
        • 2018-03-24
        • 2015-04-08
        相关资源
        最近更新 更多