在PyQT中获取布局的小部件

21

我有一个QVBoxLayout,通过addWidget()方法添加了几个小部件。现在我需要删除这些小部件,似乎我需要使用removeWidget()(它接受要删除的小部件作为参数)来实现。

我认为在我的布局上调用children()findChildren(QWidget)会返回一个包含我添加的小部件列表; 然而,在调试器中,我只收到空列表。

我是不是完全误解了什么?我刚开始学习PyQT,主要是通过API文档的试错学习。

2个回答

28
从 QLayout 中获取一个小部件,您需要调用其 itemAt(index) 方法。正如该方法名称所示,它将返回一个项目而不是小部件。在结果上调用 widget() 方法最终将给您小部件:

要从 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

1
index = myLayout.count()-1 我同意这个答案,但是-1应该放在顶部,因为索引从0开始,如果你不这样做,在循环中索引会到达-1。 - abhishek mishra

18

很奇怪,我的理解是通过addWidget添加小部件将所有权转移到布局,因此调用children()应该有效。

但是,作为替代方案,您可以使用count()itemAt(int)来循环遍历布局项目,并提供QLayoutItem以供removeItem(QLayoutItem*)使用。

编辑:

我刚刚尝试了在纯 C++ 测试应用程序中使用 addWidget。它并没有把QObject的所有权转移到布局上,所以children()确实是一个空列表。然而,文档 明确表示所有权已被转移...

编辑 2:

好吧,看起来它将所有权转移到具有该布局的窗口小部件(这并不是文档所说的)。这使得布局中的项成为 QObject 层次结构中布局本身的同级!因此,最好坚持使用 countitemAt


看起来这个方法可以解决问题,谢谢。它并不完全按照我的意愿工作,但这似乎是由于我需要解决一些独立于此的显示更新问题,需要进一步调试。 - Xiong Chiamiov
1
哦,所以 itemAt 返回一个 QWidgetItem(这需要使用 removeItem,但不知何故它不符合我的要求)。但是,如果在其上调用 .widget(),您将会得到(惊讶!)与之相关联的 QWidget,可以使用 removeWidget 删除,并设置其父项为 None - Xiong Chiamiov

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