Qt получить детей из макета - PullRequest
28 голосов
/ 01 ноября 2010

Я пытаюсь скрыть все виджеты в макете. Но похоже, что findChildren не работа для макета.

Вот мой пример кода:

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

cout << list.size() << endl;

size равно 0, но внутри этого макета у меня есть несколько виджетов. Но тот же код работает нормально, если я пытаюсь получить виджеты из родительского виджета.

Как я могу получить их из соответствующего макета?

Ответы [ 6 ]

32 голосов
/ 01 ноября 2010

Макет не «внедряет» себя в дерево родитель-потомок, поэтому виджеты остаются (прямыми) дочерними элементами своего родительского виджета.

Вместо них можно использовать QLayout::count() и QLayout::itemAt().

28 голосов
/ 23 мая 2013

Вы можете просто перебрать элементы макета, используя itemAt(), а затем проверить, является ли элемент виджетом:

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()
  }
}
4 голосов
/ 28 августа 2014

Уже очень поздно, но если кто-то найдет здесь, как я, вот мое решение: Я попытался ответить @braggPeaks (это так же, как ответ @Frank Osterfeld), но это не удалось. Затем я изменил, как это, и это работает как шарм. (Я понятия не имею, почему это работает, потому что в моем макете нет пустых элементов, но я все равно должен проверить, есть ли у него.)

for (int i = 0; i < this->layout->count(); ++i) {
    QWidget *w = this->layout->itemAt(i)->widget();
    if(w != NULL)
        w->setVisible(false);
}
1 голос
/ 17 января 2013

Поскольку макет не является частью иерархии виджетов, виджет необходимо запрашивать у родителя, но затем можно использовать indexOf, чтобы определить, принадлежит ли он и его местоположение

  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;
            }
        }
    };
0 голосов
/ 13 мая 2015

Отвечая на старый пост, но я хотел простой способ отключить все виджеты, содержащиеся в макете или любом дочернем макете.Это сработало для моих целей:

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;
}
0 голосов
/ 01 ноября 2010

Вы пробовали children() метод вместо findChildren()?Возможно, вы получаете «плохой» макет из метода widget -> findChild<QLayout *> (layoutName).Попробуйте найти детей сразу после создания макета, чтобы убедиться, что макет правильный.При этом вы сможете определить, какая функция работает неправильно.

...