2012-01-21 68 views
18

我想在小部件调整大小时采取行动。QWidget调整信号大小?

有没有一种方法可以在没有在该窗口小部件上安装事件过滤器的情况下(显然,没有子类化)呢? AFAIK,QWidget没有resized信号。

+4

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

回答

11

如果你有一个可以有严格的关系到了QWidget你可以使用QObject::installEventFilter(QObject * filter)和超载bool eventFilter(QObject *, QEvent *)任何其他的QObject。多见于Qt docs

17

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

+0

请注意,warwaruk写道“很明显,没有继承它” –

+0

@KamilKlimek,...之后我发布了答案:) – Lol4t0

+0

没有注意到,我的坏 –

9

在您使用Python和PyQt4的情况下,你可以设置widget.resizeEvent给你的函数没有sublclassing它:

#!/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_()) 
+5

这会阻止运行resizeEvent的基类实现。这可能会做一些重要的事情。使用猴子补丁解决方案时,您必须将原始方法的引用保留为单独的变量。乱。 – Chris

+2

@Chris文档说,在调用resizeEvent的时候,窗口小部件已经有了它的新几何图形,所以如果你在主窗口小部件上没有其他任何东西需要做,你可以重写该函数。我使用这种技术来调整QScrollArea的内容。 – blameless75

2

对不起,它看起来像一个黑客,但我用这样的:

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

Python的易读性设计非常多。但是,+1保留了超级实现。 –

2

这是两年太晚了,但我正在研究一个完全覆盖父项的透明覆盖小部件。你不能在没有继承的情况下做你想做的事情,但是你可以按照@reclosedev的建议将子类限制为一个实例,这意味着你不必实际创建一个子类。

我写了下面的代码片段(在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实例的子类,这意味着您不必创建实际的子类。凭借附加的方法,每个父实例将有效地成为子类的实例。

如果你需要一次性的东西,所有用于删除子类resizeEvent方法并用原来的方法替换它的代码都可以被删除。在这种情况下,该解决方案基本上是@ reclosedev解决方案的一个更有趣的版本,但是@ Chris关于保留原始地址的评论。

唯一需要注意的是,它不能正确支持GL窗口小部件,因此,例如无法将叠加窗口添加到QGraphicsView的视口中。但是,它可以添加到QGraphicsView本身。

2

您可以覆盖resizeEvent通过

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