web-dev-qa-db-ja.com

QWidgetリサイズ信号?

ウィジェットのサイズが変更されたときにアクションを実行したい。

そのウィジェットにイベントフィルターをインストールせずに(そして、明らかに、それをサブクラス化せずに)それをキャッチする方法はありますか? AFAIK、QWidgetにはresized信号がありません。

23
warvariuc

そのQWidgetと厳密な関係を持つ他のQObjectがある場合は、QObject::installEventFilter(QObject * filter)を使用し、bool eventFilter(QObject *, QEvent *)をオーバーロードできます。詳しくは Qt docs をご覧ください

12
Kamil Klimek

widgetクラスから派生し、resizeEventイベントを再実装できます

24
Lol4t0

PyQt4でPythonを使用している場合は、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_())
9
reclosedev

申し訳ありませんが、ハックのように見えますが、これを使用します。

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

これは数年遅れですが、親を完全にカバーする透明なオーバーレイウィジェットに取り組んでいました。サブクラス化せずに必要なことを行うことはできませんが、@ 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で可能な2つの巧妙なトリックを使用しています。

  • 元のメソッドは、新しいメソッドの_original属性に隠されています。関数がオブジェクトであるため、これは可能です。
  • 新しいメソッドは本当にQWidgetinstanceをサブクラス化します。つまり、実際のサブクラスを作成する必要はありません。各親インスタンスは、メソッドの追加により事実上サブクラスのインスタンスになります。

一度だけ必要な場合は、サブクラス化されたresizeEventメソッドを削除して元のメソッドで置き換えるためのすべてのコードをゴミ箱に入れることができます。その場合、解決策は基本的に@reclosedevの解決策のより洗練されたバージョンですが、@ Chrisは元のアドレスを保持することについてコメントしています。

このコードの唯一の注意点は、GLウィジェットを正しくサポートしていないため、たとえば、オーバーレイをQGraphicsViewのビューポートに常に追加できるとは限らないことです。ただし、QGraphicsView自体に追加されます。

3
Mad Physicist

あなたはresizeEventを上書きすることができます

def resizeEvent(self, newSize):
    #do code here
3
chicken-me