Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to get the sender() in a C++ lambda signal slot handler?
Forum Updated to NodeBB v4.3 + New Features

How to get the sender() in a C++ lambda signal slot handler?

Scheduled Pinned Locked Moved General and Desktop
12 Posts 7 Posters 11.7k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    philk
    wrote on last edited by VRonin
    #1

    When I call signal() from within a lambda function its always null.

    connect(senderObject, &Sender::signal, this, [=]() {
      QObject* sender = sender(); // always null?
    });
    
    1 Reply Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by VRonin
      #2

      Try with:

      connect(senderObject, &Sender::signal, this, [&]() {
        QObject* sender = sender();
      });
      

      (Z(:^

      1 Reply Last reply
      2
      • P Offline
        P Offline
        philk
        wrote on last edited by
        #3

        This does not work, sender returns nullptr.

        1 Reply Last reply
        0
        • D Offline
          D Offline
          dvolosnykh
          wrote on last edited by
          #4

          I have experienced the same problem several times.

          1 Reply Last reply
          0
          • A Offline
            A Offline
            AndreasF
            wrote on last edited by
            #5

            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();
            			}
            		});
            
            1 Reply Last reply
            2
            • aha_1980A Offline
              aha_1980A Offline
              aha_1980
              Lifetime Qt Champion
              wrote on last edited by
              #6

              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, capture senderObject instead:

              connect(senderObject, &Sender::signal, [senderObject, this]() {
                // use senderObject here
              });
              

              Works like a charm.

              Qt has to stay free or it will die.

              mrjjM 1 Reply Last reply
              7
              • aha_1980A aha_1980

                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, capture senderObject instead:

                connect(senderObject, &Sender::signal, [senderObject, this]() {
                  // use senderObject here
                });
                

                Works like a charm.

                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @aha_1980
                But what do you do when hook up multiple objects to same lambda slot ?
                Capture them all ?

                aha_1980A VRoninV 2 Replies Last reply
                0
                • mrjjM mrjj

                  @aha_1980
                  But what do you do when hook up multiple objects to same lambda slot ?
                  Capture them all ?

                  aha_1980A Offline
                  aha_1980A Offline
                  aha_1980
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  @mrjj

                  From my recent (and limited) experience, I'd say you better use the classical "member function" slot here, otherwise your code will get ugly.

                  Qt has to stay free or it will die.

                  1 Reply Last reply
                  0
                  • mrjjM mrjj

                    @aha_1980
                    But what do you do when hook up multiple objects to same lambda slot ?
                    Capture them all ?

                    VRoninV Offline
                    VRoninV Offline
                    VRonin
                    wrote on last edited by VRonin
                    #9

                    @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.

                    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                    ~Napoleon Bonaparte

                    On a crusade to banish setIndexWidget() from the holy land of Qt

                    aha_1980A 1 Reply Last reply
                    0
                    • VRoninV VRonin

                      @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.

                      aha_1980A Offline
                      aha_1980A Offline
                      aha_1980
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @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...

                      Qt has to stay free or it will die.

                      1 Reply Last reply
                      1
                      • VRoninV Offline
                        VRoninV Offline
                        VRonin
                        wrote on last edited by VRonin
                        #11

                        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));
                        

                        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                        ~Napoleon Bonaparte

                        On a crusade to banish setIndexWidget() from the holy land of Qt

                        aha_1980A 1 Reply Last reply
                        8
                        • VRoninV VRonin

                          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));
                          
                          aha_1980A Offline
                          aha_1980A Offline
                          aha_1980
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          @VRonin Cool! Will need to try this but looks promising.

                          Qt has to stay free or it will die.

                          1 Reply Last reply
                          0

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved