find all group boxes in layout
-
Hello,
I am trying to find the layout attached to a group box, with a specific title, that is inside another layout so I can add a new label that group box's layout.TestTab::TestTab(QWidget *parent) : QWidget(parent) { QVBoxLayout *mainLayout = new QVBoxLayout; QGroupBox *newGrpBox = new QGroupBox("VCM"); QVBoxLayout *grpLayout = new QVBoxLayout(newGrpBox); QLabel *tstLbl = new QLabel("Hello"); grpLayout->addWidget(tstLbl); newGrpBox->setLayout(grpLayout); mainLayout->addWidget(newGrpBox); setLayout(mainLayout); QList<QGroupBox*> childGrps = mainLayout->findChildren<QGroupBox*>(); foreach(auto obj, childGrps) { qDebug() << "found group box"; if(obj->title() == "VCM") { qDebug() << "Found box with VCM title"; QList<QVBoxLayout*> grpLay = obj->findChildren<QVBoxLayout*>(); foreach (auto layOjb, grpLay) { qDebug() << "Found grp box layout"; QLabel *newLbl = new QLabel("new lbl"); layOjb->addWidget(newLbl); } } } }
The qDebug statements do not appear from any level for the nested loops indicating that it finds no QGroupBoxes inside the mainLayout. Is there something wrong in my iteration loops? I can't declare the mainLayout to be the parent of the group box on declaration without a compiler error but I thought addWidget takes care of parenting issues and would make the group box a child of that layout. How should I go about accomplishing this task?
-
@thewiggin
You can do thisfindChildren()
stuff from widgets downward. You are trying to do it from layouts, and that's not how Qt works, parent-child-wise. See e.g. https://stackoverflow.com/questions/4065378/qt-get-children-from-layoutThe 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.
Read the comments and answers there for explanation/suggestions.
-
Thank you.
I can find the layout inside the QGroupBox based off the link you provided:
QVBoxLayout *vidGrpLay = newGrpBox->findChild<QVBoxLayout*>(); if(vidGrpLay) { qDebug() << "Found grp box layout"; QLabel *newVidGrpLbl = new QLabel("Vid property"); vidGrpLay->addWidget(newVidGrpLbl); }
I am still having trouble understanding how to use count and itemAt to do what I want.
TestTab::TestTab(QWidget *parent) : QWidget(parent) { QVBoxLayout *mainLayout = new QVBoxLayout; QGroupBox *newGrpBox = new QGroupBox("VCM"); QVBoxLayout *grpLayout = new QVBoxLayout(newGrpBox); QLabel *tstLbl = new QLabel("Hello"); grpLayout->addWidget(tstLbl); newGrpBox->setLayout(grpLayout); mainLayout->addWidget(newGrpBox); setLayout(mainLayout); QGroupBox *vidGrp; for(int i = 0; i < mainLayout->count(); ++i) { vidGrp = dynamic_cast<QGroupBox*>(mainLayout->itemAt(i)); if(vidGrp) { qDebug() << "Found a group box"; if(vidGrp->title() == "VCM") { qDebug() << "Found VCM group box"; QVBoxLayout *vidGrpLay = vidGrp->findChild<QVBoxLayout*>(); if(vidGrpLay) { qDebug() << "Found VCM grp box layout"; QLabel *newVidGrpLbl = new QLabel("Vid property"); vidGrpLay->addWidget(newVidGrpLbl); } break; } else { vidGrp = nullptr; } } } }
How do I check if the mainLayout->itemAt(i) is a QGroupBox?
-
@thewiggin said in find all group boxes in layout:
How do I check if the mainLayout->itemAt(i) is a QGroupBox?
QGroupBox *gb = qobject_cast<QGroupBox *>(mainLayout->itemAt(i)); // or dynamic_cast<>() if (gb) qDebug() << "It's a QGroupBox!";
EDIT
Oh I just saw you havevidGrp = dynamic_cast<QGroupBox*>(mainLayout->itemAt(i)); if(vidGrp)
so that should work?
-
The dynamic cast returns nothing and the qobject_cast throws a compile error:
testtab.cpp:79: error: no matching function for call to ‘qobject_cast<QGroupBox*>(QLayoutItem*)’
79 | QGroupBox vidGrp = qobject_cast<QGroupBox>(mainLayout->itemAt(i));
| ^QGroupBox *vidGrp = qobject_cast<QGroupBox*>(mainLayout->itemAt(i));
-
@JoeCFD Thanks using find child tied to object name worked
Not sure why the dynamic cast did not return it or why qobject_cast throws an error but the below snippet works when combined with the other code that has been posted.
newGrpBox->setObjectName("vidGrpBox"); QGroupBox *findGp = findChild<QGroupBox*>("vidGrpBox"); if(findGp) { QVBoxLayout *vidGrpLay = findGp->findChild<QVBoxLayout*>(); if(vidGrpLay) { qDebug() << "Found grp box layout"; QLabel *newVidGrpLbl = new QLabel("Vid property"); vidGrpLay->addWidget(newVidGrpLbl); } }
@JonB Thank you as well!