I have many QActions and I would like to connect their triggered(bool) signal to a specific slot which gets an integere number as input, let's say setX(int x). I need to specify x in connect callback. For example:
connect(actionV, &QAction::triggered,
        this, &TheClass::setX /* somehow x=10 */);
I tried using std::bind and it does not work:
connect(actionV, &QAction::triggered,
        std::bind(this, &TheClass::setX, 10));
You can solve this easily using a lambda:
connect(actionV, &QAction::triggered, [&] { 
   m_theClass.setX(10);
});
The syntax you used for std::bind was incorrect, that's why it didn't compile.
While using a lambda is faster, I am going to post some examples using std::bind for completeness shake in the hope of being helpful to other programmers as well.
Example A:
// Declaration somewhere in a header file.
void setX(int x);
/*
 * In a cpp file:
 * Notice the order of the arguments. 
 * a) The pointer to the class member
 * b) the instance of the class (in this case is "this")
 * c) The arguments to the function are the rest.
 */
connect(actionV, &QAction::triggered, this, std::bind(&MyClass::setX, this, 10));
Now, let's pretend that you must capture the parameter of a signal. In this case it's a bool. I have to remind you, that the signature is void QAction::triggered(bool checked = false).
Example B:
// Again, declaration in a header file.
void setX(bool c, int x);
/*
 * In a cpp file:
 * Notice how the emmited bool value is captured with
 * std::placeholders::_1 and then you pass 10 as well.
 */
connect(actionV,
        &QAction::triggered,
        this,
        std::bind(&MyClass::setX, this, std::placeholders::_1, 10));
To make this even more extreme, let's pretend once again that you have two overloads of setX.
Example C:
// Declaration in a header file
void setX(bool x, int x);
void setX(int x);
/*
 * In your .cpp file:
 * a) Choose the first signature
 * b) Choose the second signature
 */
connect(actionV,
        &QAction::triggered,
        this,
        std::bind(qOverload<bool, int>(&MyClass::setX),
                  this, std::placeholders::_1, 10));
// OR
connect(actionV,
        &QAction::triggered,
        this,
        std::bind(qOverload<int>(&MyClass::setX), this, 10));
But the qOverload macro needs at least a C++14 capable compiler though. You don't want to go to:
connect(actionV,
        &QAction::triggered,
        this,
        std::bind(static_cast<void(MyClass::*)(bool, int)>(&MyClass::setX),
                  this,
                  std::placeholders::_1,
                  10));
I hope I helped a bit to clarify the syntax. I can't stress enough though that using a lambda is more efficient and simple and that this was just a fun "exercise".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With