Qt get children from layout

62,547

Solution 1

The layout does not "inject" itself in the parent-child tree, so the widgets stay (direct) children of their parent widget.

You could use QLayout::count() and QLayout::itemAt() instead.

Solution 2

You can simply iterate over the layout's items, using itemAt(), then test whether the item is a widget:

for (int i = 0; i < gridLayout->count(); ++i)
{
  QWidget *widget = gridLayout->itemAt(i)->widget();
  if (widget != NULL)
  {
    widget->setVisible(false);
  }
  else
  {
    // You may want to recurse, or perform different actions on layouts.
    // See gridLayout->itemAt(i)->layout()
  }
}

Solution 3

It's very late but if anyone finds here like me, here is my solution: I tried @braggPeaks answer(it's same as @Frank Osterfeld answer) but it failed. Then I modified like this and it works like a charm. (I have no idea why it works, because my layout has no null items but still I have to check if it has.)

for (int i = 0; i < this->layout->count(); ++i) {
    QWidget *w = this->layout->itemAt(i)->widget();
    if(w != NULL)
        w->setVisible(false);
}

Solution 4

Since layout is not part of widget hierarchy, the widget has to be queried from parent but then indexOf can be used to see if it belongs and its location

  QLayout * top_l= layout(); // The parent widgets layout
   // Find your layout that you want to search inside
   QHBoxLayout * hbox = top_l->findChild<QHBoxLayout*>(QString("horizontalLayout_2"));
    if (hbox != 0) {
        std::cout << "Found horizontalLayout_2!"<<std::endl;
        QPushButton * st = findChild<QPushButton*>(QString("startButton"));

        if (st != 0) {
            std::cout << "Found startButton in top level widget"<<std::endl;
            int idx = hbox->indexOf(st);
            if (idx >=0) {
                std::cout << "Found startButton in hbox layout at location : "
                          <<idx<<std::endl;
            }
        }
    };
Share:
62,547
Alex Ivasyuv
Author by

Alex Ivasyuv

Updated on October 30, 2020

Comments

  • Alex Ivasyuv
    Alex Ivasyuv over 3 years

    I try to hide all widgets in layout. But looks like findChildren doesn't work for layout.

    Here's my sample code:

    QLayout * layout = widget -> findChild<QLayout *> (layoutName);
    QList<QWidget *> list = layout -> findChildren<QWidget *> ();
    
    cout << list.size() << endl;
    

    size is 0, but inside this layout I have a few widgets. But the same code works fine if I try to get widgets from parent widget.

    How I can get them from appropriate layout?

  • Alex Ivasyuv
    Alex Ivasyuv over 13 years
    Yes I tried children(), without any luck. I can't check after creation, as this is loaded from .ui... For widgets works fine... Issue only with layout..
  • ekhumoro
    ekhumoro almost 9 years
    The key point is that a layout can become a child of a widget (because they both inherit QObject), but a widget cannot become a child of a layout. A widget must have another widget as a parent, and QLayout does not inherit QWidget. Layouts wrap each item they contain in a QLayoutItem, and so a different set of APIs is required to access the underlying object.
  • stdcerr
    stdcerr almost 5 years
    Must be implemented in subclasses to return the layout item at index. If there is no such item, the function must return 0. that's quoted from doc.qt.io/qt-5/qlayout.html#itemAt
  • AIDoubt
    AIDoubt over 4 years
    Sucks that this comment is four years old. The way Qt even today makes QLayout keep track of the widgets inside it, is the private d_ptr and its list property. No public API...