2012-05-02 42 views
8

我有一個在切換選項時會改變的小部件。這會使所有佈局和小部件無效。我把所有佈局的列表,這樣我就可以使用類似的東西刪除他們this answer用另一種佈局替換QWidget上的佈局

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. 

我怎樣才能擺脫舊的佈局和設置新的?


的文檔quite terse,顯然不能直接適用於蟒:

QWidget.setLayout(個體經營,QLayout)

的QLayout說法有它的所有權轉移到Qt的。

將此小部件的佈局管理器設置爲佈局。

如果已經有一個佈局管理器安裝在這個小部件上,QWidget 不會讓你安裝另一個。您必須先刪除佈局管理器(由layout()返回)的現有 ,然後才能使用新佈局調用setLayout() 。

如果佈局是不同小部件上的佈局管理器,setLayout()將 重新佈局並使其成爲此小部件的佈局管理器。

實施例:

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

到調用此函數的替代方法是通過這個小部件的佈局 的構造。

QWidget將取得佈局的所有權。

另請參閱layout()和Layout Management。

回答

19

你可以簡單地重新設置父級佈局到一個臨時窗口小部件:

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

這將重新設置父級的所有子控件到臨時對象,該對象是其新的孩子一起立刻刪除,因爲我們不沒有提及它。

但是,對於單個小部件具有多個佈局並且能夠在它們之間切換的典型方式是使用QStackedWidgetQStackedLayout


如果你仍然需要回答這個問題,二級:

如何先刪除舊的佈局?

看來你不能直接刪除有一個父母的QObject,因爲父母保持對該對象的引用。但是你可以將對象添加到一個臨時QObjectCleanupHandler其中,像上面的解決方案,將與對象(S)後直接包含被刪除:

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

+1的'QObjectCleanupHandler()'解決刪除佈局。 – astrojuanlu