在PyQt布局中遍历小部件

16 投票
5 回答
37455 浏览
提问于 2025-04-16 12:43

我的问题跟在PyQT中获取布局的控件有点关系,但并不是重复的问题。我不是想要一个高层次的战略视角,而是想了解最简单、最直接的方法。因为PyQt是Qt C++ API的一个精确绑定,所以它提供了一种类似C语言的方式来获取布局中的控件。以下是我一直在使用的这种方式:

for i in range(layout.count()):
  item = layout.itemAt(i)
  if type(item) == QtGui.QLayoutItem:
    doSomeStuff(item.layout())
  if type(item) == QtGui.QWidgetItem:
doSomething(item.widget())

我不是最有经验的Python程序员,但我觉得这有点不符合Python的风格。我的直觉告诉我,在理想情况下,Python代码应该更像这样:

for w in layout.widgets():
  doSomething(w)

我错了吗?我是不是漏掉了更好的写法?在PyQt中遍历控件的方式是最好的选择吗?我习惯用C++思维,所以有时候会错过一些“显而易见”的Python特性,这些特性能让事情变得更简单。我做的部分工作是递归地深入到有布局的控件中,再到有控件的布局(等等……),以便在运行时自动连接在Designer中制作的UI。再加上QTabWidgets和处理Designer中设置的动态属性,我的代码基本上能工作,但总感觉很笨重。

5 个回答

12

只是想说一句,

items = (layout.itemAt(i) for i in range(layout.count())) 
for w in items:
   doSomething(w)

我试了第一个答案,但发现它返回的是一个WidgetItem类型,所以我其实做了一些修改:

widgets = (layout.itemAt(i).widget() for i in range(layout.count())) 
for widget in widgets:
   if isinstance(widget, QLineEdit):
        print "linedit: %s  - %s" %(widget.objectName(), widget.text())
   if isinstance(widget, QCheckBox):
        print "checkBox: %s  - %s" %(widget.objectName(), widget.checkState())
28

这是一个很晚的回复,但我觉得这可能对将来的人有用。我当时也在寻找这个问题的答案。不过,我想要识别小部件的类型,这样我就可以根据不同类型来处理它们。下面是我找到的示例代码:

for widget in centralwidget.children():
    if isinstance(widget, QLineEdit):
        print "linedit: %s  - %s" %(widget.objectName(),widget.text())

    if isinstance(widget, QCheckBox):
        print "checkBox: %s  - %s" %(widget.objectName(),widget.checkState())

希望这对某一天的某个人有帮助。:)

10

你可以把这些小部件放进一个生成器里,像这样:

items = (layout.itemAt(i) for i in range(layout.count())) 
for w in items:
   doSomething(w)

如果你发现自己经常使用这个方法,可以把这段代码放进一个生成器函数里,这样更方便:

def layout_widgets(layout):
   return (layout.itemAt(i) for i in range(layout.count()))


for w in layout_widgets(layout):
   doSomething(w)

撰写回答