Navigating widgets in PyQt layout

My question is somewhat related to Getting layout widgets in PyQT , but this is not a duplicate. Instead of looking for a high-level strategic view of how to do this, I try to understand what might be the most idiomatic and easiest way to do this. Since PyQt is a fairly accurate Qt C ++ API binding, it provides a C-ish way to get widgets in a layout. Here is the idiom I used:

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 guy in Python, but that seems messy. My intuition tells me that in an ideal world, Python code should look something like this:

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

Am I really wrong? Did I miss the highest idiom? Is this the best possible way to iterate over widgets in PyQt? I tend to think in C ++, so sometimes I miss the "obvious" features of the Python language that improve the situation. Part of what I am doing is recursively descending into widgets with layouts with widgets with layouts (etc.), to automatically connect to the user interface created in Designer at runtime. Add QTabWidgets and handle the dynamic properties set in the designer, and my code basically works, but it just feels awfully awkward.

+4
source share
4 answers

You can put widgets in the generator like this:

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

If you end up using this a lot, you can paste this code into the generator function:

 def layout_widgets(layout): return (layout.itemAt(i) for i in range(layout.count())) for w in layout_widgets(layout): doSomething(w) 
+5
source

This is a very late answer, but I thought it might be useful for future confirmation. I also searched for the answer to this question. But I wanted to define widget types so that I could handle them accordingly. Here is a sample 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 someday this will be useful to someone. :)

+11
source

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 found that it returns a WidgetItem type, so I actually made a revision:

 widgets = (layout.itemAt(i).widget() for i in range(layout.count())) for w 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()) 
+1
source

I believe that you already have the simplest solution to this problem. PyQt (and PySide) are basically just wrappers around the C ++ API. They add additional pythonic support in several areas: signals / slots, basic types such as QString, etc., but for the most part, everything remains exactly the same as in the C ++ API.

Of course, this should not stop you from creating your own more pythonic library.

0
source

Source: https://habr.com/ru/post/1341746/


All Articles