2012-02-21 90 views
3

我試圖找到一些需要qt佈局並刪除它的一切。只是想象中的窗口是什麼樣子 - 我有:刪除小部件和佈局以及

QVBoxLayout 
    | ------QHboxLayout 
       |---------QWidget 
    | ------QHboxLayout 
       |---------QWidget 
      ......... 

所以我需要的東西,我可以打電話給遞歸清楚,從我的父母QVBoxLayout刪除所有的東西。我嘗試過這裏提到的東西(Clear all widgets in a layout in pyqt),但它們都不起作用(無論如何都沒有正確答案)。我的代碼如下所示:

def clearLayout(self, layout): 
    for i in range(layout.count()): 
     if (type(layout.itemAt(i)) == QtGui.QHBoxLayout): 
      print "layout " + str(layout.itemAt(i)) 
      self.clearLayout(layout.itemAt(i)) 
     else: 
      print "widget" + str(layout.itemAt(i)) 
      layout.itemAt(i).widget().close() 

但它給出了一個錯誤:

   layout.itemAt(i).widget().close() 
      AttributeError: 'NoneType' object has no attribute 'close' 

=>編輯 這還挺工程(但不是否有任何其他LayoutHBoxLayout

def clearLayout(self, layout): 
    layouts = [] 
    for i in range(layout.count()): 
     if (type(layout.itemAt(i)) == QtGui.QHBoxLayout): 
      print "layout " + str(layout.itemAt(i)) 
      self.clearLayout(layout.itemAt(i)) 
      layouts.append(layout.itemAt(i)) 
     else: 
      print "widget" + str(layout.itemAt(i)) 
      if (type(layout.itemAt(i)) == QtGui.QWidgetItem): 
       layout.itemAt(i).widget().close() 

回答

11

清除佈局的最安全的方法是提取其takeAt方法的項目,然後用deleteLater明確刪除任何小部件:

def clearLayout(self, layout): 
    if layout is not None: 
     while layout.count(): 
      item = layout.takeAt(0) 
      widget = item.widget() 
      if widget is not None: 
       widget.deleteLater() 
      else: 
       self.clearLayout(item.layout()) 
+0

這是一個更優雅的解決方案。謝謝 – tisaconundrum 2016-12-27 22:16:02

7

與您的代碼問題是QLayout.itemAt()返回一個QLayoutItem,QWidgetItemQSpacerItem,取決於該位置的物品。所以條件:

type(layout.itemAt(i)) == QtGui.QHBoxLayout 

永遠True,你會試圖做.widget()QLayoutItem和返回None。因此,你得到的錯誤。另一件事是,你需要向後循環。因爲從頭開始移除物品會改變物品並改變物品的順序。

你需要寫你的函數是這樣的:

def clearLayout(self, layout): 
    for i in reversed(range(layout.count())): 
     item = layout.itemAt(i) 

     if isinstance(item, QtGui.QWidgetItem): 
      print "widget" + str(item) 
      item.widget().close() 
      # or 
      # item.widget().setParent(None) 
     elif isinstance(item, QtGui.QSpacerItem): 
      print "spacer " + str(item) 
      # no need to do extra stuff 
     else: 
      print "layout " + str(item) 
      self.clearLayout(item.layout()) 

     # remove the item from layout 
     layout.removeItem(item)  
+0

幾乎在那裏,但不完全:)謝謝無論如何:)當我運行的功能,你提供我所有的QHboxLayouts獲得clasified作爲間隔。由於這不是真的,「根據該位置的項目返回QLayoutItem,QWidgetItem或QSpacerItem。」 =>我itemAt返回QHboxLayout這不是QLayoutItem – kosta5 2012-02-21 10:16:23

+0

我sorta固定它像這樣︰def clearLayout(self,layout): 我在範圍內(layout.count()): if(type(layout.itemAt(i) )== QtGui.QHBoxLayout): 打印 「佈局」 + STR(layout.itemAt(I)) self.clearLayout(layout.itemAt(I)) 其他: 打印 「小工具」 + STR(layout.itemAt (i)) if(type(layout.itemAt(i))== QtGui.QWidgetItem): layout.itemAt(i).widget()。close() – kosta5 2012-02-21 10:17:06

+0

@ user965847:這很奇怪。我爲我的試驗獲得了'QLayoutItem's。無論如何,我編輯了代碼。試試這個。 – Avaris 2012-02-21 10:32:05