Reputation: 1576
I have a set of buttons in a group:
buttons = new QButtonGroup();
button_0 = new MyButton("A", this);
button_1 = new MyButton("B", this);
button_2 = new MyButton("C", this);
MyButton is a QPushButton, which inherits QAbstractButton. One MyButton in the group can be selected at a time.
MyButton::MyButton(const QString &text, QWidget *parent)
: QPushButton(text, parent)
{
this->setCheckable(true);
this->setChecked(false);
}
MyButton has an increment method.
void MyButton::increment()
{
this->j++;
}
I want to call the increment method on whichever MyButton instance is currently selected. There's a handy checkedButton()
method that I can call on buttons
, but that returns a pointer to a QAbstractButton.
I can't call increment
on the pointer or the QAbstractButton. buttons->checkedButton()->increment();
yields error: no member named 'increment' in 'QAbstractButton'
. How can I increment the selected MyButton?
Upvotes: 1
Views: 114
Reputation: 38909
You just need to let the compiler know that you are using a MyButton*
rather than a QAbstractButton*
, and that means a cast.
If you know that the pointer is a MyButton*
then you can just do a static_cast<MyButton*>(buttons->checkedButton())->increment();
If you don't know if its a MyButton*
then you'll need to check, and that'll mean something like this:
MyButton* temp = dynamic_cast<MyButton*>(buttons->checkedButton());
if(temp != nullptr) temp->increment();
EDIT:
SaZ has pointed out that qobject_cast
is preferable to dynamic_cast
because:
It doesn't require RTTI support and it works across dynamic library boundaries
MyButton
already inherits from QObject
, but there is one more qualification, that it is declared with Q_OBJECT
. If both of these qualifications are met then you can simply replace the dynamic_cast
with a qobject_cast
:
MyButton* temp = qobject_cast<MyButton*>(buttons->checkedButton());
if(temp != nullptr) temp->increment();
Upvotes: 2
Reputation: 15081
For the sake of completeness, in the case of Qt program you may also make use of signal-slot system: if increment
was declared to be a slot
then this would work:
QMetaObject::invokeMethod(abstractButton, "increment");
Upvotes: -1
Reputation: 49279
Note that in the case of QObject
derived classes, you can and should use qobject_cast()
instead of dynamic cast. It is more efficient by employing the Qt meta system.
Also, unlike the dynamic cast, it will work when compiling without RTTI, and with dynamic libraries as well.
Upvotes: 2
Reputation: 24068
Dynamic cast QAbstractButton
to MyButton
and call increment()
.
QAbstractButton* abstractButton = buttons->checkedButton();
MyButton* myButton = dynamic_cast<MyButton*>(abstractButton);
if (myButton)
{
myButton->increment();
}
Upvotes: 1