我有一个QVBoxLayout
,通过addWidget()
方法添加了几个小部件。现在我需要删除这些小部件,似乎我需要使用removeWidget()
(它接受要删除的小部件作为参数)来实现。
我认为在我的布局上调用children()
或findChildren(QWidget)
会返回一个包含我添加的小部件列表; 然而,在调试器中,我只收到空列表。
我是不是完全误解了什么?我刚开始学习PyQT,主要是通过API文档的试错学习。
要从 QLayout 获取小部件,必须调用其 itemAt(index)
方法。 正如此方法的名称所示,它会返回一个项目而不是小部件。 调用结果的 widget()
方法最终将给您小部件:
myWidget = self.myLayout.itemAt(index).widget()
要移除一个小部件,请将其父小部件设置为None
:
myWidget.setParent(None)
同时非常有用的是QLayout count()
方法。要查找并删除布局中的所有内容:
index = myLayout.count()
while(index >= 0):
myWidget = myLayout.itemAt(index).widget()
myWidget.setParent(None)
index -=1
很奇怪,我的理解是通过addWidget
添加小部件将所有权转移到布局,因此调用children()
应该有效。
但是,作为替代方案,您可以使用count()
和itemAt(int)
来循环遍历布局项目,并提供QLayoutItem
以供removeItem(QLayoutItem*)
使用。
编辑:
我刚刚尝试了在纯 C++ 测试应用程序中使用 addWidget
。它并没有把QObject
的所有权转移到布局上,所以children()
确实是一个空列表。然而,文档 明确表示所有权已被转移...
编辑 2:
好吧,看起来它将所有权转移到具有该布局的窗口小部件(这并不是文档所说的)。这使得布局中的项成为 QObject
层次结构中布局本身的同级!因此,最好坚持使用 count
和 itemAt
。
itemAt
返回一个 QWidgetItem(这需要使用 removeItem
,但不知何故它不符合我的要求)。但是,如果在其上调用 .widget()
,您将会得到(惊讶!)与之相关联的 QWidget,可以使用 removeWidget
删除,并设置其父项为 None
。 - Xiong Chiamiov
index = myLayout.count()-1
我同意这个答案,但是-1应该放在顶部,因为索引从0开始,如果你不这样做,在循环中索引会到达-1。 - abhishek mishra