3

From a given widget, is it possible to get the layout that contains it?

I'm doing a dynamic form, and my widget hierarchy looks like:

QDialogBox
|- QVBoxLayout
  |- QHBoxLayout 1
    |- Widget 1
    |- Widget 2
    |- ...
  |- QHBoxLayout 2
    |- Widget 1
    |- Widget 2
    |- ...
  |- ...

If I receive a signal from Widget 1 or Widget 2, I can identify it using sender() function. I'd like to be able to adjust some properties of other widgets on the same line. How can I get a reference to the QHBoxLayout containing a given widget?

parent() property gives me the QDialogBox, since the parent of a widget cannot be a layout. layout() property gives me None, since it refers to the contained layout, not the containing layout.

Charles Brunet
  • 21,797
  • 24
  • 83
  • 124

1 Answers1

2

In your case, the following should work (I tested on a similar setup):

# Starting from Widget_1 get a list of horizontal layouts contained by QVBoxLayout
# Widget_1.parent() returns the QDialogBox
# .layout() returns the containing QVBoxLayout
# children returns layouts in QVBoxLayout, including QHBoxLayout 1-N
# if you know that there are only QHBoxLayouts, you don't need to filter
hlayouts = [layout for layout in Widget_1.parent().layout().children()
            if type(layout) == PySide.QtGui.QHBoxLayout]

def layout_widgets(layout):
    """Get widgets contained in layout"""
    return [layout.itemAt(i).widget() for i in range(layout.count())]

# then find hlayout containing Widget_1
my_layout = next((l for l in hlayouts if Widget_1 in layout_widgets(l)), None)

I'm using next() to find the first layout containing your widget (see https://stackoverflow.com/a/2748753/532513). For more readability you could use a for loop, but next() is cleaner.

Adam Sirrelle
  • 357
  • 8
  • 18
Charl Botha
  • 4,373
  • 34
  • 53
  • Yes, I ended doing something similar. But I was wondering if there would be a better way than looping through all the layout items. – Charles Brunet May 21 '13 at 15:56