从布局中删除所有项

2024-03-29 05:34:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图找到一个qt布局,并从中删除所有内容。想象一下窗户的样子-我有:

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

所以我需要一些可以递归调用的东西来清除和删除父项中的所有内容。我试过这里提到的东西(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()

Tags: inself内容closeiftypewidgetprint
2条回答

代码的问题是QLayout.itemAt()返回QLayoutItemQWidgetItemQSpacerItem,具体取决于该位置的项。所以情况是:

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

永远不会是True,您将尝试为QLayoutItem执行.widget(),并返回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)    

清除布局最安全的方法是使用其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())

相关问题 更多 >