How to get the sender() in a C++ lambda signal slot handler?
-
When I call signal() from within a lambda function its always null.
connect(senderObject, &Sender::signal, this, [=]() { QObject* sender = sender(); // always null? });
-
Try with:
connect(senderObject, &Sender::signal, this, [&]() { QObject* sender = sender(); });
-
This does not work, sender returns nullptr.
-
I have experienced the same problem several times.
-
I know, it's an old thread, but for information:
QLineEdit* senderObject = new QLineEdit(this); connect(senderObject, &QLineEdit::returnPressed, [senderObject, this]() { if (senderObject && !senderObject->text().simplified().isEmpty()) { QString txt = senderObject->text().simplified(); Icons()[txt]; senderObject->close(); iconListModel_->clearModelData(true); iconListModel_->setModelData(); } });
-
Hi all,
I just encountered the same problem and the correct solution is this: https://stackoverflow.com/questions/19719397/qt-slots-and-c11-lambda
In short: don't use
sender()
within the lambda, capturesenderObject
instead:connect(senderObject, &Sender::signal, [senderObject, this]() { // use senderObject here });
Works like a charm.
-
@aha_1980
But what do you do when hook up multiple objects to same lambda slot ?
Capture them all ? -
From my recent (and limited) experience, I'd say you better use the classical "member function" slot here, otherwise your code will get ugly.
-
@mrjj said in How to get the sender() in a C++ lambda signal slot handler?:
But what do you do when hook up multiple objects to same lambda slot ?
if they are all pointers just use
[=]
. The compiler will take care to capture all and nothing more than what you need. -
@VRonin said in How to get the sender() in a C++ lambda signal slot handler?:
if they are all pointers just use [=]. The compiler will take care to capture all and nothing more than what you need
Yeah, but you still need to find out which one emitted the signal inside the lambda...
-
Alternatively use
std::bind
const auto myLambda = [](QObject* sender, bool pressed)->void{ QPushButton* const senderButton= qobject_cast<QPushButton*>(sender); Q_ASSERT(senderButton); qDebug() << senderButton->text() << pressed; }; QObject::connect(button1,&QPushButton::clicked,std::bind(myLambda,button1,std::placeholders::_1)); QObject::connect(button2,&QPushButton::clicked,std::bind(myLambda,button2,std::placeholders::_1));
-
@VRonin Cool! Will need to try this but looks promising.