Ответ 1
Макет не "внедряет" себя в родительское дочернее дерево, поэтому виджеты остаются (прямыми) дочерними элементами своего родительского виджета.
Вместо этого вы можете использовать QLayout::count()
и QLayout::itemAt()
.
Я пытаюсь скрыть все виджеты в макете. Но похоже, что FindChildren не работа для макета.
Вот мой пример кода:
QLayout * layout = widget -> findChild<QLayout *> (layoutName);
QList<QWidget *> list = layout -> findChildren<QWidget *> ();
cout << list.size() << endl;
размер равен 0, но внутри этого макета у меня есть несколько виджетов. Но тот же код отлично работает, если я пытаюсь получить виджеты из родительского виджета.
Как я могу получить их из соответствующего макета?
Спасибо,
Макет не "внедряет" себя в родительское дочернее дерево, поэтому виджеты остаются (прямыми) дочерними элементами своего родительского виджета.
Вместо этого вы можете использовать QLayout::count()
и QLayout::itemAt()
.
Вы можете просто перебирать элементы макета, используя 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()
}
}
Поскольку макет не является частью иерархии виджетов, виджет должен быть запрошен у родителя, но затем 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;
}
}
};
Это очень поздно, но если кто-нибудь найдет здесь, как я, вот мое решение: Я попробовал ответить @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);
}
Ответ на старый пост, но мне нужен простой способ отключить все виджеты, содержащиеся в макете или любом дочернем макете. Это работало для моих целей:
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;
}
Попробовал ли вы children()
метод вместо findChildren()
? Возможно, вы получаете "плохой" макет из метода widget -> findChild<QLayout *> (layoutName)
. Попробуйте найти детей сразу после создания макета - так что вы уверены, что макет правильный. Таким образом, вы сможете определить, какая функция работает неправильно.