How to refer to the button inside of her signal function?
-
Main::Main(QWidget *parent) : QMainWindow(parent) { ui.setupUi(this); return; } void Main::on_toolButton_released() { // this-> return; }
In this example
this->
refers to the classMain
, how do I refer to the button with belongs to the function_released
?I mean, there's another keyword than
ui.<buttonanme>
?
in this caseui.toolButton
-
Hi
qobject_cast will return nullptr when the cast is not possible so its safe to do so IF you check the variable before use.so its not like a c type cast that can crash the program if wrong.
but one must check the variable before use :)
-
Hi
ui.<buttonanme> is they way to address widgets you made via Designer.
For widgets you dynamically create, then only the fucntion findchildren or you can store the pointers (like UI does) and
use them in that way.Sorry totally got something else from question.
You are asking how to know the button that was clicked / released.
-
@mrjj said in How to refer to the button 'obj' inside of her signal function?:
For widgets you dynamically create, then only the fucntion findchildren or you can store the pointers (like UI does) and
use them in that way.Could you give an example, please?
-
@n34rt
Sorry . just realized i misread you question.you can use sender() to know which button
void Main::on_toolButton_released() { QPushButton *btn = qobject_cast<QPushButton *>( sender() ); if (bnt) { // use it } }
Also just for information. you can also use lambdas as slot and capture the button (also for widgets in UI)
QPushButton* loadTextFileButton = new QPushButton("load"); connect(loadTextFileButton, &QPushButton::clicked, [loadTextFileButton]() { qDebug()<<"clicked"; loadTextFileButton->xxxxxx });
-
@mrjj thank you, this is what I was looking for.
Is it possible to get the
*btn
object without declaring the button 'type'QPushButton
?I mean something like:
auto *btn = qobject_cast<??>( sender() );
where??
is something containing the button type. -
@n34rt said in How to refer to the button inside of her signal function?:
@mrjj thank you, this is what I was looking for.
Is it possible to get the
*btn
object without declaring the button 'type'QPushButton
?I mean something like:
auto *btn = qobject_cast<??>( sender() );
where??
is something containing the button type.well the ?? could have to be the real type or else compiler would be mad but
what do you need it for ?
If you have mixed Toolbuttons and pushbuttons we could make a helper func to get it but
I need to understand the use case. :) -
@mrjj said in How to refer to the button inside of her signal function?:
or else compiler would be mad
I love the way you phrase things :)
@n34rt said in How to refer to the button inside of her signal function?:
I mean something like:
auto *btn = qobject_cast<??>( sender() );
where??
is something containing the button type.No, you can't achieve what you are aiming at like this. You need an actual type name for the
??
which you are asking C++ to actually cast to. And once you put that there you may as well equally replace theauto
with that, that's allauto
does for you, it's not "magic" in any way.If you are asking: what can I do if the
sender()
might be either aQPushButton
or (say) aQLabel
and I need to know which for my following code, just put in multiple separate casts:QPushButton *btn = qobject_cast<QPushButton *>( sender() ); QLabel *lbl = qobject_cast<QLabel *>( sender() ); if (btn) ... else if (lbl) ... else if ....
-
@JonB said in How to refer to the button 'obj' inside of her signal function?:
QPushButton *btn = qobject_cast<QPushButton *>( sender() );
QLabel *lbl = qobject_cast<QLabel *>( sender() );
if (btn) ...
else if (lbl) ...
else if ....Interesting, suppose the
sender()
is aQLabel*
and I write
QPushButton *btn = qobject_cast<QPushButton *>( sender() );
its an invalid cast? won't cause the program to crash?
Isn't it a 'bad practice' to do such a thing?If not, inside of a if else, possible to check the button type in a switch?
-
Hi
qobject_cast will return nullptr when the cast is not possible so its safe to do so IF you check the variable before use.so its not like a c type cast that can crash the program if wrong.
but one must check the variable before use :)
-
You need an actual type name for the ?? which you are asking C++ to actually cast to.
While yes, that is true, it's worth noting that QObject::sender() returns
QObject *
, which means that you can introspect the sender, without needing to first cast to an derived type. For example,// we don't know what type `sender` is, but it *must* be QObject-derived (if not nullptr). QObject * const sender = sender(); if (sender) { qDebug() << sender->metaObject()->className(); // eg "QPushButton" // just for fun: if (sender->metaObject()->inherits("QAbstractButton")) { // it was a button. } }
Is It possible to get the signal type from the *btn? I mean in if its Button_released Button_pressed etc?
Yes, sort of. Have a look at QObject::senderSignalIndex(). eg:
QObject * const sender = sender(); if ((sender) && (senderSignalIndex() >= 0)) { QMetaMethod method = sender->metaObject()->method(senderSignalIndex); if (method.isValid()) { // inspect / do stuff with `method`. } }
Be sure to read the warnings documented for QObject::senderSignalIndex() though. eg:
Warning: This function violates the object-oriented principle of modularity. However, getting access to the signal index might be useful when many signals are connected to a single slot.
I would generally avoid using QObject::senderSignalIndex(), and if I did use it, would probably only ever use it when
sender() == this
. Any other time would smell like a bad design.Cheers.
-
@n34rt
I would avoid usingsender()
at all. I have never needed to. Since Qt5 accepted lambdas --- to which you can pass your own parameters --- for slots, it is preferable to pass the sender as an explicit parameter rather than trying to usesender()
to refer to it. Example:connect(btn, &QPushButton::clicked, this, [btn, this]() { qDebug() << btn->objectName(); this->someFunction(btn); });