Подтвердить что ты не робот

Qt получает детей от макета

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

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

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

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

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

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

Спасибо,

4b9b3361

Ответ 1

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

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

Ответ 2

Вы можете просто перебирать элементы макета, используя 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()
  }
}

Ответ 3

Поскольку макет не является частью иерархии виджетов, виджет должен быть запрошен у родителя, но затем 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;
            }
        }
    };

Ответ 4

Это очень поздно, но если кто-нибудь найдет здесь, как я, вот мое решение: Я попробовал ответить @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);
}

Ответ 5

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

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;
}

Ответ 6

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