Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Using findChild to iterate over controls and perform the same actions with them.



  • Hi!
    Sometimes it is required to perform the same action with several controls.
    And I'm too lazy to do this:

    const QString s = "00";
    ui->lineEdit1->setText(s);
    ui->lineEdit2->setText(s);
    ui->lineEdit3->setText(s);
    ui->lineEdit4->setText(s);

    There may be more controls. I came up with the following way:

    const QString s = "00";
    int i = 1;
    while (i<5)
    {
    QLineEdit * ed = this->findChild<QLineEdit *>("lineEdit"+QString::number(i));
    ed->setText(s);
    i++;
    }

    It certainly works. The question is: is it good to do this? Maybe there are some non-obvious problems that I will create for myself? What will the respected community say?



  • @Oleg_P
    Here we go... It's fine. It's slightly slower to look them up than have it resolved at compile-time. Also be aware that if this has many children that's a lot to look through. You might save the results in an array for re-use. You should always check the result being != nullptr. I wouldn't use it by habit, but it's good for e.g. visit a bunch of widgets and do something common to them.



  • @Oleg_P
    Here we go... It's fine. It's slightly slower to look them up than have it resolved at compile-time. Also be aware that if this has many children that's a lot to look through. You might save the results in an array for re-use. You should always check the result being != nullptr. I wouldn't use it by habit, but it's good for e.g. visit a bunch of widgets and do something common to them.


  • Moderators

    Hi, welcome to the forum.

    Well yeah, it works, but it certainly wouldn't pass my review.
    It's so slow in comparison and my heart just bleeds thinking about all those CPU cycles and battery life that could have been saved.
    I mean it's not even shorter:

    const QString s = "00";ui->lineEdit1->setText(s);ui->lineEdit2->setText(s);ui->lineEdit3->setText(s);ui->lineEdit4->setText(s);
    
    const QString s = "00";int i = 1;while (i<5){QLineEdit * ed = this->findChild<QLineEdit *>("lineEdit"+QString::number(i));ed->setText(s);i++;}
    

    I see absolutely no reason to do this.



  • Hi!
    Thanks a lot for the answers!

    I understand that the program will be slower . But I really want to be able to do repetitive actions with controls in the cycle.

    I really liked John's idea of ​​an array. In this case, I don't need a search.

    QLineEdit * arr_ed[4]; - In the class header.

    I know exactly how many controls I have and their names.
    I have enough will to write once in the constructor:

    arr_ed[0] = ui->lineEdit1;
    arr_ed[1] = ui->lineEdit2;
    arr_ed[2] = ui->lineEdit3;
    arr_ed[3] = ui->lineEdit4;
    

    One time is definitely enough. :)
    And then I can perform as many actions as I want:

    const  QString s = "00";
    for (int i = 0; i<4; i++)
    {
        arr_ed[i]->setText(s);
    }
    

    or
    arr_ed[i]->setText("Anything else");

    or
    arr_ed[i]->clear();

    -in different cases. I can call any method I need depending on the situation.


  • Moderators

    If you really have to at least don't hardcode the array size. At some point you will change the size and then you will have to fix all the places. You will likely forget one and get an out of bound access error.

    for (auto le : arr_ed)
       le->setText(s);
    


  • Of course, I'm not talking about all the controls in the program. I don't need it. This is purely for the case where there are few lineEdit. To erase the text in them all, or write something the same. Or to change the color of all the buttons for example. Then I'm going to need a separate array of pointers on the buttons. Of course, I'm not going to collect in one array of pointers for the controls of different purposes. There will be no practical benefit to this.


Log in to reply