在PyQt布局中遍历小部件
我的问题跟在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)