2012-01-21 13 views
18

Desidero eseguire un'azione quando un widget è stato ridimensionato.Segnale di ridimensionamento QWidget?

C'è un modo per catturarlo senza installare un filtro eventi su quel widget (e, ovviamente, senza sottoclassi)? AFAIK, QWidget non ha un segnale resized.

+4

No, non puoi. La modalità bset è: Crea il tuo QWidget che emette Resize in resizeEvent(), quindi promuovi i tuoi widget :) –

risposta

11

Se avete qualche altra QObject che può avere rigorosa rispetto a quella QWidget è possibile utilizzare QObject::installEventFilter(QObject * filter) e il sovraccarico bool eventFilter(QObject *, QEvent *). See more at Qt docs

17

è possibile derivare da widget classe e reimplementare resizeEvent evento

+0

nota che warwaruk ha scritto "e, ovviamente, senza sottoclassi" –

+0

@KamilKlimek, ...dopo aver postato la risposta :) – Lol4t0

+0

non ho notato che, il mio male –

9

Nel caso in cui si sta utilizzando Python con PyQt4, è possibile impostare widget.resizeEvent alla funzione senza sublclassing esso:

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

Ciò impedisce l'esecuzione della classe base di resizeEvent. Potrebbe fare qualcosa di importante. E con la soluzione patch-scimmia, dovresti mantenere un riferimento al metodo originale come variabile separata. Disordinato. – Chris

+2

@Chris I documenti dicono che al momento resizeEvent è chiamato il widget ha già la sua nuova geometria, quindi se non hai altro da fare sul widget principale puoi semplicemente sovrascrivere la funzione. Io uso questa tecnica per ridimensionare il contenuto di un QScrollArea. – blameless75

2

Ci dispiace ma sembra un hack, ma io uso questo:

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

Così tanto per Python che è stato progettato per la leggibilità. Tuttavia, +1 per conservare la super implementazione. –

2

Questo è un paio di anni troppo tardi, ma stavo lavorando a un widget di sovrapposizione trasparente che coprirebbe completamente il genitore. Non puoi fare ciò che vuoi senza sottoclassi, ma puoi limitare la sottoclasse a un'istanza come suggerisce @reclosedev, il che significa che non devi creare effettivamente una sottoclasse.

ho scritto il seguente frammento (che lavora in PyQt4) per seguire la dimensione di qualsiasi widget che il widget viene aggiunto:

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

Questo codice utilizza un paio di trucchetti che sono possibili con Python:

  • Il metodo originale è nascosto nell'attributo _original di quello nuovo. Questo è possibile perché le funzioni sono oggetti.
  • Il nuovo metodo sottoclasse effettivamente qualsiasi QWidgetistanza, il che significa che non è necessario creare una sottoclasse effettiva. Ogni istanza genitore diventerà effettivamente un'istanza di una sottoclasse in virtù del metodo virato sul metodo.

Se avete bisogno di una cosa di una volta, tutto il codice per la rimozione del resizeEvent metodo di sottoclasse e la sua sostituzione con l'originale può essere cestinato. In tal caso, la soluzione è fondamentalmente una versione più elaborata della soluzione di @ reclosedev, ma con i commenti di @ Chris sulla conservazione dell'originale indirizzato.

L'unico avvertimento con questo codice è che non supporta correttamente i widget GL, quindi ad esempio l'overlay non può sempre essere aggiunto al viewport di un QGraphicsView. Tuttavia, può essere aggiunto allo stesso QGraphicsView.

2

è possibile ignorare il resizeEvent da

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