2012-04-17 14 views
11

Stavo guardando l'esempio here e mi chiedevo se non ci fossero perdite di memoria. Ho redatto l'articolo parlando del subjet mem leak on delete. Tuttavia, mentre i QWidgets mantengono la proprietà del widget aggiunto, il layout no.Il proprietario di QBoxLayout diventa il proprietario di tutti i widget di layout?

Sembra dal codice QT che il genitore con il layout, ottiene la proprietà di tutti i widget per questo layout. Tuttavia non ho potuto vedere alcun riferimento di questo nei documenti.

Window::Window() 
{ 
editor = new QTextEdit(); 
QPushButton *sendButton = new QPushButton(tr("&Send message")); 

connect(sendButton, SIGNAL(clicked()), this, SLOT(sendMessage())); 

QHBoxLayout *buttonLayout = new QHBoxLayout(); 
buttonLayout->addStretch(); 
buttonLayout->addWidget(sendButton); 
buttonLayout->addStretch(); 

QVBoxLayout *layout = new QVBoxLayout(this); 
layout->addWidget(editor); 
layout->addLayout(buttonLayout); 

setWindowTitle(tr("Custom Type Sending")); 
} 
+0

Sebbene le classi derivate non lo menzionino, la classe di layout di base (QLayout) dice che 'addWidget' chiama' addItem' ... e 'addItem' dice: *" ** Nota: ** La proprietà dell'oggetto viene trasferito al layout ed è responsabilità del layout cancellarlo. "* http://doc.qt.nokia.com/4.7-snapshot/qlayout.html # addItem – HostileFork

+0

@HostileFork la proprietà dell'elemento * * viene trasferita al layout. Non è la proprietà del widget stesso. Vedi la mia [risposta] (http://stackoverflow.com/a/38003370/1951907) che cerca di chiarire questo punto. – Boris

risposta

15

Da Layout Management:

Suggerimenti per l'Utilizzo dei layout

Quando si utilizza un layout, non è necessario passare un genitore quando costruire i widget figlio. Il layout sarà automaticamente reparent i widget (utilizzando QWidget :: setParent()) in modo che siano figli del widget su cui è installato il layout.

Nota: i widget in un layout sono figli del widget su cui è installato il layout , non del layout stesso. I widget possono avere solo altri widget come genitore, non come layout.

È possibile nidificare i layout utilizzando addLayout() su un layout; il layout interno diventa quindi figlio del layout in cui è inserito.

+1

Non ho cercato questo. La ringrazio per la risposta. – Anton

+0

Come nota aggiuntiva, "proprietà" viene comunque assegnata al layout, mentre l'assegnazione genitore viene assegnata al widget principale del layout: http://doc.trolltech.com/4.7/qlayout.html#addItem – jdi

+0

@jdi la proprietà dell'elemento * * viene trasferita al layout. Non è la proprietà del widget stesso. Vedi la mia [risposta] (http://stackoverflow.com/a/38003370/1951907) che cerca di chiarire questo punto. Il proprietario di un QWidget (nel senso di gestione della memoria) è sempre il suo widget genitore, e quindi non può essere un layout. – Boris

2

No, QLayout non assume la proprietà dei QWidgets gestiti.

Qui è l'attuazione di addWidget():

void QLayout::addWidget(QWidget *w) 
{ 
    addChildWidget(w); 
    addItem(QLayoutPrivate::createWidgetItem(this, w)); 
} 

Spiegazione:

  1. addChildWidget() assicura semplicemente che il riuscito widget di w è rimosso da altri layout.

  2. createWidgetItem(this, w) alloca un nuovo QWidgetItem. Questo QWidgetItem memorizza un puntatore a w, ma non assume la proprietà di w.

  3. addItem() aggiunge la voce al layout, e prende possesso della QWidgetItem (non del QWidget osservato dal QWidgetItem). Ciò significa che QWidgetItem verrà distrutto quando viene distrutto QLayout. Tuttavia, QWidget w non sarà ancora distrutto.

QWidget verrà distrutto quando il suo parente QWidget viene distrutto. Tale genitore viene assegnato automaticamente da QLayout quando viene chiamato genitore-> setLayout (layout).

Problemi correlati