2012-05-02 18 views
8

Ho un widget che cambia quando viene attivata un'opzione. Ciò invalida tutti i layout e i widget. Io continuo elenco di tutti i layout, quindi posso eliminarli utilizzando qualcosa di simile a this answer:sostituzione del layout su un QWidget con un altro layout

class MyWidget(QFrame): 
    # ... 
    def reLayout(self): 
     def deleteLayoutChilds(l): 
     while l.count(): 
      item=l.takeAt(0) 
      widget=item.widget() 
      if widget: widget.deleteLater() 
      else: deleteLayoutChilds(item.layout()) 
     for l in self.allLayouts: deleteLayoutChilds(l) 

     # now install the new layout 
     ## 
     ## how to delete the old layout first? 
     l=self.layout(); del l # no effect 
     # 
     layout=QGridLayout(self) 
     ## warning: QLayout: Attempting to add QLayout "" to MyWidget "", which already has a layout. 

Come posso eliminare il vecchio layout e impostare quello nuovo?


La documentazione è quite terse e apparentemente non direttamente applicabile al pitone:

QWidget.setLayout (auto, QLayout)

L'argomento QLayout ha la proprietà trasferita al Qt.

Imposta il layout manager per questo widget sul layout.

Se sul widget è già installato un gestore di layout, QWidget non consente di installarne un altro. È necessario prima eliminare il gestore di layout esistente (restituito da layout()) prima di poter chiamare setLayout() con il nuovo layout.

Se il layout è il gestore di layout su un altro widget, setLayout() risolverà il layout e lo renderà il gestore di layout per questo widget.

Esempio:

QVBoxLayout *layout = new QVBoxLayout; 
layout->addWidget(formWidget); 
setLayout(layout); 

Un'alternativa a chiamare questa funzione è quello di passare questo widget per il costruttore della layout di .

QWidget diventerà proprietario del layout.

Vedere anche layout() e Gestione layout.

risposta

19

Si può semplicemente Reparent il layout di un widget temporanea:

def reLayout(self): 
    QWidget().setLayout(self.layout()) 
    layout = QGridLayout(self) 
    ... 

Che vi Reparent tutti i widget figlio a quella oggetto temporaneo, e che oggetto viene eliminato immediatamente insieme con i suoi nuovi figli perché noi don 't mantenere un riferimento ad esso.

Tuttavia, il modo tipico per disporre di più layout per un singolo widget e poter passare da uno all'altro è utilizzare uno QStackedWidget o QStackedLayout.


E se hai ancora bisogno la risposta a questa questione secondaria:

come eliminare il vecchio layout di prima?

Sembra che non sia possibile eliminare direttamente un QObject con un genitore, poiché il genitore mantiene un riferimento a tale oggetto.Ma si può aggiungere l'oggetto ad una temporanea QObjectCleanupHandler che, come la soluzione di cui sopra, sarà cancellato con l'oggetto (s) contiene immediatamente:

QObjectCleanupHandler().add(self.layout()) 
+1

+1 per il 'QObjectCleanupHandler()' soluzione per eliminare il layout . – astrojuanlu

Problemi correlati