1
votes

I have a QPushButton and when I click the button I will call a method that take two parameters, in this example: exampleMethod(int i, double d).

Now I connect the click event from QPushButton button to the exampleMethod like this:
connect(button, &QPushButton::clicked,this, &Example::exampleMethod);

But this doesn't work because the parameter of clicked() and exampleMethod(int, double) are not compatible.

Now I created a extra signal: exampleSignal(int i, double d) to connect to my slot:
connect(this, &Example::exampleSignal, this, &Example::exampleMethod);

And a additional slot with no parameters: exampleMethodToCallFromButtonClick() to call it from QPushButton clicked() in which I call the signal:

Example::Example(QWidget *parent) : QWidget(parent){

    button = new QPushButton("Click", this);

    connect(button, &QPushButton::clicked,this, &Example::exampleMethodToCallFromButtonClick);
    connect(this, &Example::exampleSignal, this, &Example::exampleMethod);
}

void Example::exampleMethod(int i, double d){
    qDebug() << "ExampleMethod: " << i << " / " << d;
}

void Example::exampleMethodToCallFromButtonClick(){
    emit exampleSignal(5,3.6);
}

This works fine.

1) Now my first question: Is this realy the best way to do this without lambda?

With lambda it looks even nicer and I don't need two connect statements:
connect(button, &QPushButton::clicked, [this]{exampleMethod(5, 3.6);});

2) My second question: with lamba is this the best way to do this or are there any better ways to solve it?

I also considered to save the parameters from exampleMethod as a member variable, call the method without parameter and get instead of the parameters the member variables but I think thats not a so good way.

Thanks for your help!

2
lambda is a good way.Tazo leladze
In exampleMethodToCallFromButtonClick(), no need to use signals to call exampleMethod. You can call the fuction directly without relying on SIGNAL/SLOTElcan
Where do 5 and 3.6 come from? If you get them from some calculation, you can do it in a slot without passing in as parametersJerry
Thanks, for your answers, your all right. @Jerry the 5 and 3.6 will come from a QTextEditMorchul
"With lambda it looks even nicer" is not a comment I see every day. :) But seriously, if you're using a button click to emit a signal based on some parameter values, just persist/store/serialize those values, which are presumably editable using some other widgets. Simple enough, yes?Rethunk

2 Answers

3
votes

I wouldn't do either of those things. Receive the signal, gather your parameters and then just call exampleMethod. A lambda is more appropriate when the parameters are known at the point where you connect.

Example::Example(QWidget *parent) : QWidget(parent){

    button = new QPushButton("Click", this);

    connect(button, &QPushButton::clicked, this, &Example::onButtonClicked);
}

void Example::exampleMethod(int i, double d){
    qDebug() << "ExampleMethod: " << i << " / " << d;
}

void Example::onButtonClicked(){
    int i = ...;
    double d = ...;
    exampleMethod(i, d);
}
1
votes

In addition to the single-method approach in the other answer, perhaps the values of i and d are unrelated and it'd make sense to factor them out to their own methods:

int Example::iValue() const {
  ...
}

double Example::dValue() const {
  ...
}

Then, the following are equivalent:

connect(..., this, [this]{ exampleMethod(iValue(), dValue()); });
connect(..., this, std::bind(&Example::exampleMethod, this, iValue(), dValue()));

The choice between onButtonClicked() and the use of iValue() and dValue() is determined mostly by whether the values are useful when factored out separately, and whether for code comprehension it makes sense to specify the call at the connect site, or move it out to an individual method.

Finally, if you do use the single-method approach, and the button is instantiated with setupUi, i.e. you've designed Example in Designer, you can save the connect call by naming the handler method appropriately:

Q_SLOT void Example::on_button_clicked();

The button here is the name of the button object in the .ui file. The connection will be made automatically by Ui::Example::setupUi(QWidget*).