Qt get children from layout

2019-03-14 15:54发布

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?

6条回答
狗以群分
2楼-- · 2019-03-14 15:59

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()
  }
}
查看更多
Deceive 欺骗
3楼-- · 2019-03-14 15:59

Responding to an old post, but I wanted a simple way to disable all widgets contained in a layout or any child-layout. This worked for my purposes:

void setEnabledWidgetsInLayout(QLayout *layout, bool enabled)
{
   if (layout == NULL)
      return;

   QWidget *pw = layout->parentWidget();
   if (pw == NULL)
      return;

   foreach(QWidget *w, pw->findChildren<QWidget*>())
   {
      if (isChildWidgetOfAnyLayout(layout,w))
         w->setEnabled(enabled);
   }
}

bool isChildWidgetOfAnyLayout(QLayout *layout, QWidget *widget)
{
   if (layout == NULL or widget == NULL)
      return false;

   if (layout->indexOf(widget) >= 0)
      return true;

   foreach(QObject *o, layout->children())
   {
      if (isChildWidgetOfAnyLayout((QLayout*)o,widget))
         return true;
   }

   return false;
}
查看更多
太酷不给撩
4楼-- · 2019-03-14 16:00

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);
}
查看更多
疯言疯语
5楼-- · 2019-03-14 16:10

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.

查看更多
乱世女痞
6楼-- · 2019-03-14 16:18

Did you try children() method instead of findChildren() ? Maybe you are getting a 'bad' layout from widget -> findChild<QLayout *> (layoutName) method. Try to find children right after creating the layout - so you are sure the layout is correct. Doing so you will be able do determine what function works wrong.

查看更多
啃猪蹄的小仙女
7楼-- · 2019-03-14 16:22

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;
            }
        }
    };
查看更多
登录 后发表回答