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?
-
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 ifthis
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. -
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.
-
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.