Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loop over widgets in PyQt Layout

Tags:

python

pyqt

My question is somewhat related to Get a layout's widgets in PyQT but it's not a duplicate. Instead of looking for a high level strategic view of how to do it, I'm trying to understand what the most idiomatic and straightforward way to do it would be. Since PyQt is a pretty exact binding of the Qt C++ API, it presents a C-ish way to get at widgets in a layout. Here is the sort of idiom I have been using:

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())

I'm not the most experienced Python guy, but this seems somewhat unpythonic. My intuition is telling me that in an ideal world, the Python code should look something more like:

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

Am I wrong? Am I missing a superior idiom? Is this the best possible way to iterate over widgets in PyQt? I tend to think in C++, so I sometimes miss out on "obvious" Python language features that make things better. Part of what I'm doing is recursively descending into widgets with layouts with widgets with layouts (etc...) to automatically wire up connections to UI's made in Designer at run time. Add in QTabWidgets, and handling of the dynamic properties set in designer, and my code basically works, but it just feels horribly clunky.

like image 665
wrosecrans Avatar asked Mar 01 '11 03:03

wrosecrans


2 Answers

This is a very late response but I thought it might be useful for future refence. I was looking for the answer to this question also. But I wanted to identify widget types so I could handle them accordingly. Here is example code of what I found:

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())

I hope that will be useful for someone someday. :)

like image 82
Paul Avatar answered Oct 25 '22 20:10

Paul


Just a comment,

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

I tried the first answer but I found that it returns a WidgetItem type, so actually I did a revision:

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())
like image 25
lsheng Avatar answered Oct 25 '22 19:10

lsheng