获取PyQT布局中的小部件

22 投票
2 回答
42653 浏览
提问于 2025-04-16 00:11

我有一个 QVBoxLayout,我通过 addWidget() 方法往里面添加了一些小部件(也就是按钮、文本框等)。现在我需要删除这些小部件,似乎需要用 removeWidget() 方法(这个方法需要传入要删除的小部件)来完成这个操作。

我以为调用 children() 或者 findChildren(QWidget) 方法可以得到我添加的那些小部件的列表,但我现在在调试器里,结果却得到了空列表。

我是不是理解错了什么?我上周刚开始学习 PyQT,主要是通过试错和查阅文档来学习的。

2 个回答

30

要从一个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
20

这真奇怪。我理解的是,通过 addWidget 添加小部件会把它的所有权转给布局,所以调用 children() 应该是可以的。

不过,作为替代方案,你可以通过使用 count()itemAt(int) 来循环遍历布局中的项目,然后把 QLayoutItem 传给 removeItem(QLayoutItem*)

编辑:

我刚刚在一个简单的 C++ 测试应用中尝试了 addWidget,结果发现它并没有把 QObject 的所有权转给布局,所以 children() 确实是一个空列表。不过,文档上明确说所有权是会转移的……

编辑 2:

好吧,看起来它是把所有权转给了拥有这个布局的小部件(这和文档说的并不一样)。这就意味着布局中的项目在 QObject 的层级结构中是布局本身的兄弟!所以,使用 countitemAt 会更简单。

撰写回答