Search code examples
c++qtlambdaqt-signalsqt-connection

Qt - modify slot's parameter of previous connected signal using lambda function


I'm trying to reconnect a signal to the same slot but with a different parameter. This would work if I just wanted to reconnect the same signal to a diferent slot without using parameters or lambda functions but I need to do it this way.

At first I tried something like this:

connect(remove_btn,&QPushButton::clicked,[this, id] {function1(varA);});
connect(remove_btn,&QPushButton::clicked,[this, id] {function1(varB);});

function1 receives varA and never varB.

I found a way to do this by keeping a list of the connections and when I wanted to modify the parameter I would just disconnect the old one and make a new connection.

What I'd like to know is if is there a way to make this modification without the need of keeping track of all the connections and go through the discconnect/connect process.


Solution

  • Two solutions come to my mind:

    1. Capture var by reference and change it instead of reconnecting:

      class Foo : public QWidget {
        Q_OBJECT
        int remove_btn_var;
        int varA = 10, varB = 20;
        QPushButton remove_btn;
        void function1(int);
      public:
        Foo() {
          remove_btn_var = varA;
          connect(&remove_btn, &QPushButton::clicked, [&] { function1(remove_btn_var); });
        }
        void switch() {
          remove_btn_var = varB;
        }
      };
      
    2. Add a property to the button that you can modify:

      static const char k_function1_var[] = "function1_var";
      class Foo : public QWidget {
        Q_OBJECT
        int varA, varB;
        QPushButton remove_btn;
        void function1(int);
      public:
        Foo() {
          remove_btn.setProperty(k_function1_var, varA);
          connect(&remove_btn, &QPushButton::clicked, [this] { 
            function1(remove_btn.property(k_function1_var).toInt())
          });
        }
        void switch() {
          remove_btn.setProperty(k_function1_var, varB);
        }
      };