PyQt如何从布局中移除一个布局

5
datainputHbox = QHBoxLayout()
layout = QVBoxLayout(self)
layout.addLayout(datainputHbox)


pagedatainputdeletboxbutton1.clicked.connect(lambda:self.boxdelete(datainputHbox))

def boxdelete(self, box):

这是关于PyQt程序的内容。如何编写boxdelete函数以便从布局中删除datainputHbox的数据?我尝试了很多方法,但只能删除所有小部件,而不能删除布局。


1
嗯,我真的以为有一个“removeLayout”函数... - jonspaceharper
4个回答

7
作为一般性的回答:来源于这里,但需要稍微做出重要的更改:不应该调用widget.deleteLater()。至少在我的情况下,这会导致Python崩溃。 全局函数
def deleteItemsOfLayout(layout):
     if layout is not None:
         while layout.count():
             item = layout.takeAt(0)
             widget = item.widget()
             if widget is not None:
                 widget.setParent(None)
             else:
                 deleteItemsOfLayout(item.layout())

连同Brendan Abel's答案中的boxdelete函数一起

def boxdelete(self, box):
    for i in range(self.vlayout.count()):
        layout_item = self.vlayout.itemAt(i)
        if layout_item.layout() == box:
            deleteItemsOfLayout(layout_item.layout())
            self.vlayout.removeItem(layout_item)
            break

2

你可以通过获取相应的 QLayoutItem 并将其删除来删除 QLayouts。此外,您还应该存储对您的布局的引用,否则除非您知道它们属于哪个小部件,否则没有其他方法在以后访问它们。

datainputHbox = QHBoxLayout()
self.vlayout = QVBoxLayout(self)
layout.addLayout(datainputHbox)
pagedatainputdeletboxbutton1.clicked.connect(lambda: self.boxdelete(datainputHbox))

def boxdelete(self, box):
    for i in range(self.vlayout.count()):
        layout_item = self.vlayout.itemAt(i)
        if layout_item.layout() == box:
            self.vlayout.removeItem(layout_item)
            return

removeItem 不会完全删除对象,这可能会导致由于其引用计数器/垃圾回收器而在 Python 中保留该对象。根据 [pyqt5 文档][https://doc.qt.io/qt-5/qlayout.html#removeItem],“从布局中移除布局项 item。调用者有责任删除该项。” - A. Hendry

1

一个函数可以实现TheTrowser的回答,较为简洁:

def clear_item(self, item):
    if hasattr(item, "layout"):
        if callable(item.layout):
            layout = item.layout()
    else:
        layout = None

    if hasattr(item, "widget"):
        if callable(item.widget):
            widget = item.widget()
    else:
        widget = None

    if widget:
        widget.setParent(None)
    elif layout:
        for i in reversed(range(layout.count())):
            self.clear_item(layout.itemAt(i))

1
使用上述内容,我编写了一个函数,可以删除所有布局及其小部件。不幸的是,它也会破坏其他实例中的相应布局和小部件,因此请谨慎使用。
def clearLayout(self, layout: QLayout):
    """
    Args:
        layout (QLayout): The layout to clear
    """
    if layout is not None:
        while layout.count():
            item = layout.takeAt(0)
            if item is not None:
                while item.count():
                    subitem = item.takeAt(0)
                    widget = subitem.widget()
                    if widget is not None:
                        widget.setParent(None)
                layout.removeItem(item)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接