2012-02-21 91 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