web-dev-qa-db-fra.com

QWidget redimensionner le signal?

Je souhaite effectuer une action lorsqu'un widget a été redimensionné.

Y a-t-il un moyen d'attraper cela sans installer un filtre d'événement sur ce widget (et, évidemment, sans le sous-classer)? AFAIK, QWidget n'a pas de signal resized.

23
warvariuc

Si vous avez un autre QObject qui peut avoir une relation stricte avec ce QWidget, vous pouvez utiliser QObject::installEventFilter(QObject * filter) et surcharger bool eventFilter(QObject *, QEvent *). Voir plus sur Qt docs

12
Kamil Klimek

Vous pouvez dériver de la classe widget et réimplémenter l'événement resizeEvent

24
Lol4t0

Si vous utilisez Python avec PyQt4, vous pouvez définir widget.resizeEvent à votre fonction sans la sous-classer:

#!/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

Désolé, cela ressemble à un hack, mais j'utilise ceci:

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

C'est quelques années trop tard, mais je travaillais sur un widget de superposition transparent qui couvrirait complètement le parent. Vous ne pouvez pas faire ce que vous voulez sans sous-classe, mais vous pouvez limiter la sous-classe à une instance comme le suggère @reclosedev, ce qui signifie que vous n'avez pas besoin de créer réellement une sous-classe.

J'ai écrit l'extrait suivant (qui fonctionne dans PyQt4) pour suivre la taille de n'importe quel widget auquel le widget est ajouté:

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())

Ce code utilise quelques astuces qui sont possibles avec Python:

  • La méthode d'origine est cachée dans le _original attribut du nouveau. Cela est possible car les fonctions sont des objets.
  • La nouvelle méthode sous-classe vraiment tout QWidgetinstance, ce qui signifie que vous n'avez pas besoin de créer une sous-classe réelle. Chaque instance parent deviendra effectivement une instance d'une sous-classe grâce à la méthode clouée.

Si vous avez besoin d'une chose unique, tout le code pour supprimer la méthode sous-classée resizeEvent et la remplacer par l'original peut être mis à la corbeille. Dans ce cas, la solution est essentiellement une version plus sophistiquée de la solution de @ reclosedev, mais avec les commentaires de @ Chris sur la préservation de l'original adressé.

La seule mise en garde avec ce code est qu'il ne prend pas correctement en charge les widgets GL, par exemple, la superposition ne peut pas toujours être ajoutée à la fenêtre d'affichage d'un QGraphicsView. Elle peut, cependant, être ajouté au QGraphicsView lui-même.

3
Mad Physicist

Vous pouvez remplacer le resizeEvent par

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