Perché QWidget :: paintEvent non viene chiamato?
-
10-07-2019 - |
Domanda
Ho una semplice gerarchia di widget: GraphWidget - > MotionWidget - > NodeWidget. Sono nuovo di Qt, quindi non sono ancora sicuro di come funzionino alcuni interni. Fondamentalmente, GraphWidget crea un singolo MotionWidget M e imposta il genitore M su se stesso. M quindi scompare e crea un mucchio di NodeWidgets. Tuttavia, NodeWidgets non viene mai dipinto, né viene chiamata la loro funzione paintEvent ().
Ho provato a creare MotionWidget direttamente, senza GraphWidget e tutto funziona. Quindi perché le cose si rompono se aggiungo GraphWidget alla gerarchia?
Ecco un incolla con i relativi bit di codice dal mio progetto. Ho anche incluso l'output di GraphWidget :: dumpObjectTree () in alto.
Modifica: dimenticato di includere il collegamento incolla;) http://rafb.net/p/Zp39CF94 .html
Aggiornamento: ho avvolto MotionWidget in un layout.
Prima:
GraphWidget :: GraphWidget( QWidget *parent ) : QWidget( parent )
{
setFixedSize( 500, 500 );
MotionWidget *n = new MotionWidget( 5, this );
}
Dopo
GraphWidget :: GraphWidget( QWidget *parent ) : QWidget( parent )
{
setFixedSize( 500, 500 );
QVBoxLayout *l = new QVBoxLayout;
MotionWidget *n = new MotionWidget( 5 );
l->addWidget( n );
setLayout( l );
}
Ora, quest'ultimo funziona. Cioè tutto viene disegnato. La domanda diventa quindi ... Perché? Perché non ha funzionato nel primo caso, ma ha funzionato nel secondo?
Soluzione
Non condividerò la la risposta di Aiua . Passare il genitore a un oggetto aggiungerà il figlio alla gerarchia visiva. (Altrimenti, usare Designer per creare un widget che includa altri, ma con un posizionamento assoluto, non funzionerebbe.) Tuttavia, probabilmente c'erano altri fattori che impedivano che il dipinto accadesse.
A causa del fatto che il layout ha fatto funzionare le cose, ho intenzione di indovinare che in entrambe le versioni, MotionWidget
non ha dimensioni impostate. Ciò significherebbe nel primo esempio che sarebbe dimensionato a 0x0 pixel, che Qt ottimizzerà quando proverà a dipingere. Nel secondo esempio, il layout controlla la dimensione dei widget aggiunti ad esso, quindi allargherebbe MotionWidget
, e quindi inizierebbe a ricevere nuovamente gli eventi di disegno.
Per risolvere questo problema, è possibile impostare la dimensione in modo esplicito come si fa per GraphWidget
, oppure è possibile eseguire alcune dimensioni dinamiche in base alle dimensioni del genitore, oppure GraphWidget
potrebbe controllare la dimensione o una qualsiasi delle numerose opzioni disponibili. Anche i layout possono essere belli, ma non sono assolutamente necessari.