Search code examples
c++arraysqtqt-designerboost-preprocessor

Populating array with sequentially named ui objects from Qt form


I have a Qt project with an ui made in Qt Designer. The ui currenlty contains 16 QLabels. I need to have an array with all of the QLabels. Currently I initialize the array with:

labels_ = {ui->label0, ui->label1, ui->label2, ui->label3, ui->label4,
           ui->label5, ui->label6, ui->label7, ui->label8, ui->label9,
           ui->label10, ui->label11, ui->label12, ui->label13, ui->label14,
           ui->label15};

I would like to be able to later easily add and remove QLabels to the ui form. What if at some point I would like to test the program with 100 QLabels?

I found out that with Boost.preprocessor I could achieve this:

#define NLABELS 16
#define FILL_ARRAY(z, idx, name) \
    BOOST_PP_CAT(name, idx), 

labels_ = {BOOST_PP_REPEAT(NLABELS, FILL_ARRAY, ui->label)};

However, I am still hesitant whether this is the right approach or not. Maybe Qt has some other functionality to achieve this?


Solution

  • With Qt you can use the findChildren function:

        QList<QLabel*> list = this->findChildren<QLabel*>(QRegularExpression("label\\d+$"));
    

    This will return a QList of pointers to QLabels children of this that are named labelX (where X is at least one digit).

    LE: By reading the comments i assume it's not sorted the way you want, so you can sort the strings numerically by using the QCollator like this:

    QCollator c;
    c.setNumericMode(true);
    
    std::sort(list.begin(), list.end(), [&c](QLabel* lhs, QLabel* rhs) {
        if(c.compare(lhs->objectName(), rhs->objectName()) < 0)
            return true;
        return false;
    });