nilkkiz
nilkkiz

Reputation: 41

Finding QGridLayout elements in Qt

I created labels and added them to the layout. How to get the elements from the layout? I tried to use method children(), but it gives empty list... Is there a way to get them? Some sample code below.

QGridLayout* layout = new QGridLayout();
QLabel* test = new QLabel();
test->setPixmap(m_staticStorage->getFirstImg());
test->setScaledContents(true);

QLabel* test2 = new QLabel();
test2->setMaximumSize(50,50);
test2->setPixmap(m_staticStorage->getSecondImg());
tes2->setScaledContents(true);

layout->addWidget(worker, 0, 0);
layout->addWidget(farmer, 0, 1);
ui->verticalLayout->addLayout(layout);
//layout->children() ->>>> empty

Upvotes: 2

Views: 1855

Answers (2)

Maxim Paperno
Maxim Paperno

Reputation: 4869

This will iterate over any QLayout subclass to find the items which have been added so far:

  for (int i=0; i < layout->count(); ++i) {
    QLayoutItem *item = layout->itemAt(i);
    if (!item || !item->widget())
      continue;
    QLabel *label = qobject_cast<QLabel*>(item->widget());
    if (label) {
      // .... do stuff with label
    }
  }

One can also iterate in a similar fashion over each row or column of a QGridLayout using QGridLayout::columnCount() or QGridLayout::rowCount() and then QGridLayout::itemAtPosition() to get the actual QLayoutItem.

If you need to uniquely identify the QLabel after finding it, you could for example give each label a unique objectName or do a setProperty() on them with a unique ID when creating them.

QLabel *test1 = new QLabel(this);
test1->setObjectName(QStringLiteral("test1"));

....
     if (label) {
       if (!label->objectName().compare(QLatin1String("test1")))
          // this is "test1" label
     }
QLabel *test1 = new QLabel(this);
test1->setProperty("id", 1);

....
     if (label) {
       if (label->property("id").toInt() == 1)
          // this is "test1" label
     }

Upvotes: 2

Marcus
Marcus

Reputation: 1930

Better to use the function QObject::findChild

Qt is returning all children of a given Type and Objectname. You can decide to get only direct children or also all recursively.

this->findChild<QLabel*>(QString(), Qt::FindDirectChildrenOnly);

This will return all direct children of this (where this is your parent widget, not your layout) with any name and of type QLabel*

Your approach do not work because the layout do not take the ownership of the labels:

From Layout Management:

Tips for Using Layouts

When you use a layout, you do not need to pass a parent when constructing the child widgets. The layout will automatically reparent the widgets (using QWidget::setParent()) so that they are children of the widget on which the layout is installed.

Note: Widgets in a layout are children of the widget on which the layout is installed, not of the layout itself. Widgets can only have other widgets as parent, not layouts.

You can nest layouts using addLayout() on a layout; the inner layout then becomes a child of the layout it is inserted into.

BTW: Don't forget to set a parent for your layout

QGridLayout* layout = new QGridLayout(this);

and for your labels too

QLabel* test2 = new QLabel(this);

Upvotes: 1

Related Questions