Custom Class findChild<QPushButton *>(); Not Finding Child
-
QPushButton *numButtons[15]; for(int i = 0; i<11; i++){ QString buttonName = "Button" + QString::number(i); numButtons[i] = makeCallDialog::findChild<QPushButton *>(buttonName); qDebug() << "Button: " << numButtons[i]; qDebug() << buttonName; connect(numButtons[i], &QPushButton::released, this, &makeCallDialog::numPressed); }
I have 10 QPushButtons (Button0, Button1, ..., Button9). I am trying to connect them via this for() loop, but Connect() returns with invalid null parameter. I have determined that the findChild<...> code isn't finding the element/ child. Why would this happen?
makeCallDialog is my class name. Also, I am not using the Designer to create the UI.
-
Hi
Should that not be
makeCallDialog->findChild<QPushButton *>(buttonName);
as FindChild is not static ?also, you did call
pushButton0->setObjectName("Button0");
etc..
when you created them ?
The Text on button is not their name. -
When I change it to your suggestion I get the error: 'makeCallDialog' does not refer to a value
But I did not setObjectName. Making this change solve my problem. Thank you!
How is the object name different from the variable name? I assumed that whatever I name a variable is its object name.
-
@Burke212 said in Custom Class findChild<QPushButton *>(); Not Finding Child:
How is the object name different from the variable name? I assumed that whatever I name a variable is its object name.
Hi
the variable name is a local thing you use to store a pointer to the object in.
FindChild has no way of knowing such names.
The objectName however, is a property of the object, much like its size and color and
Qt/FindChild know of this pr design.
And just like its size, its part of the object. The variable name , you use is not part of the object and
therefore not related to the variable name at all. -
Hi,
I think the easiest way would be, if you use an iterator to go through your QList of QPushButtons and connect the current QPushButton while iterating. You can also rename your Buttons during this process.
EDIT: Where do you create your Buttons?
QPushButton *num[10];
Does not create an array of 10 (usable) PushButton-Objects. You define 10 pointers to a QPushButton there, but no QPushButton is initialized.
Better:QPushButton myBtn; // Calls Std-Constructor of QPushButton // OR QPushButton *myBtn = new QPushButton ();
I dont get the use of findChild there... If you are trying to "find" the buttons, that were created somewhere else (in parent class), to connect them, why dont you connect them directly in your parent class? (something like sending a signal to notify your Dialog that "Button Nr. X" was pressed / released)
-
I don't have a QList of QPushButtons, I simply declare the buttons in the header, then define them in cpp.
In header:
QPushButton *Button0; ... QPushButton *Button9;
In cpp:
Button0 = new QPushButton(this); .... Button9 = new QPushButton(this);
The *QPushButton num[10] is going to store the button's names & connect them to numPressed().
numButtons[i] = makeCallDialog::findChild<QPushButton *>(buttonName);
connect(numButtons[i], &QPushButton::released, this, &makeCallDialog::numPressed);
So the idea is numButtons[0] is set to Button0, then Button0 is connected to numPressed(), and so forth with the other elements in the array.
-
@Burke212 Just some side notes from my side.
It is not common do define a class name with starts with lowcase. A good pratice is to have class names calmelcase starting with upper case (makeCallDialog should by MakeCallDialog) and variable name starting with low case.Second: why do you use sereval variables and not a container like QVector
in header
QVector<QPushButton*> myButtons;
in cpp:
... for(int idx = 0; idx < 10; ++idx) { myButtons << new QPushButton(this); connect(myButtons.last(), &QPushButton::released, this, &makeCallDialog::numPressed); } ...
-
@Burke212 this works in tutorial, because QPushButton instance are defined with .ui and eah one has a name
"Button0" to "Button9", this has no link with variable name.
To made this work, you must do:
Button0 = new QPushButton(this); Button0->setObjectName("Button0"); .... Button9 = new QPushButton(this); Button9->setObjectName("Button9");
or
... for(int idx = 0; idx < 10; ++idx) { myButtons << new QPushButton(this); myButtons.last()->setObjectName(QStringLiteral("Button%1").arg(idx)); connect(myButtons.last(), &QPushButton::released, this, &makeCallDialog::numPressed); } ...
-
One more thing... :)
So you create 10 Buttons and connect them somehow to "numPressed", that prints or computes the button-number, if a button is clicked + released, right?The use of a QButtonGroup would make this even easier.
https://doc.qt.io/qt-5.6/qbuttongroup.htmlAdd your buttons to your buttonGroup and setID of each button.
ButtonGroup also provides signals and functions to work with. Maybe your own connection is not necessary anymore and you dont need to rename every single button, because you can work with the groupID.When adding the buttons to your group, set your own IDs, as the default buttonID in a buttonGroup starts at -2 and decreases with every additional button (this gave me headache in one of my projects some time ago... Of course, I didnt set my own IDs and was expecting the ID to start at 0 increasing. And of course I didnt read the Docs of the addButton-Function back then) :)