Lambda that uses signal argument to connect to a slot
-
@ofmrew said in Lambda that uses signal argument to connect to a slot:
[this]( ){ ^ | here
This is where you put arguments in a lambda. For example:
[this](int someInt) { qDebug() << someInt; }
-
@sierdzio What if the someInt in your response is created on the fly and only exists as an argument in the signal. I has no name; that is why in my example code I had to declare a variable in which to store a value and be able to address it by name.
-
From what you wrote, the signature of
mouseLoc
isMyCanvas::mouseLoc(int someInt)
so that's exactly the use case ofsomeInt
. -
@ofmrew said in Lambda that uses signal argument to connect to a slot:
@sierdzio What if the someInt in your response is created on the fly and only exists as an argument in the signal. I has no name; that is why in my example code I had to declare a variable in which to store a value and be able to address it by name.
Does not matter if it has a name or not. Compiler cares for number of arguments and their types, not how they are called.
-
@ofmrew
With the warning that I don't do C++ now and when I did I didn't use lambdas... but I can't help sticking my neck out :)A lambda is essentially a call to an anonymous function, with nasty syntax. If you wrote your slot as a function, you would pass a parameter for the string (received from the signal) to it, wouldn't you? Like:
void slot(const QString& st) { this->ui->statusBar->showMessage(st, 0); }
So when you want to do that in lambda, @sierdzio is telling you that the formal parameter belongs inside the
()
. Sooo... I believe you want:connect(ui->canvas, &MyCanvas::mouseLoc, [this](const QString& st){this->ui->statusBar->showMessage(st, 0);});
We could lay it out so we can see what it is going on:
connect(ui->canvas, &MyCanvas::mouseLoc, [this](const QString& st) { this->ui->statusBar->showMessage(st, 0); } );
See how it's really the same syntax as when you do it with an explicit function?
-
Where is mouseLoc used ?
-
@SGaist ```
/void MyCanvas::mouseMoveEvent(QMouseEvent *e)
{
qDebug() << e << this->rect();
QPoint mouseLocation = e->pos();
qDebug() << mouseLocation;
QPoint worldPosition = currentMatrix.inverted().map(mouseLocation);
QString x = QString::number(worldPosition.rx());
QString y = QString::number(worldPosition.ry());
QString pt = x.append(":");
mouseLocString = pt.append(y);
emit mouseLoc(mouseLocString);
if (currentAction == 2){
corner2Ptw = e->pos();
this->update();
}
}This is the code workaround that declares mouseLocString. I would like to eliminate that step. I am, however, beginning to believe that it is a futile effort. Like I said above, I should just declare the signal with both parameters and connect it to the StatusBar slot. But I wanted to see how far I can push the boundaries of lambda. I find them very useful. Sorry if I have wasted your time.
-
Eliminate what step ?
-
@ofmrew said in Lambda that uses signal argument to connect to a slot:
connect(ui->canvas, &MyCanvas::mouseLoc, [=](MyCanvas::mouseLoc(QString st)){ui->statusBar->showMessage(st, 0)};));
connect(ui->canvas, &MyCanvas::mouseLoc, [](QPoint p)
{
ui->statusBar->showMessage(QString("%1:%2").arg(p.x()).arg(p.y()));
}); -
You can't avoid the connection step. Otherwise, how would Qt know what to call ?
-
@ofmrew said in Lambda that uses signal argument to connect to a slot:
@JonB Still no dice. I tried:
connect(ui->canvas, &MyCanvas::mouseLoc, [=](MyCanvas::mouseLoc(QString st)){ui->statusBar->showMessage(st, 0)};));
No type named mouseLoc.
But @JonB wrote you exactly what code to use and you tried something else. Try what he proposed.
-
@ofmrew said in Lambda that uses signal argument to connect to a slot:
@sierdzio I tried:
connect(ui->canvas, &MyCanvas::mouseLoc, [this](const QString& st) {this->ui->statusBar->showMessage(st, 0);});
And it worked. Thanks everyone, I learned something.
Cheers :-)
For the future, one more recommendation:
connect(ui->canvas, &MyCanvas::mouseLoc, this, // <- control object [this](const QString& st) {this->ui->statusBar->showMessage(st, 0);});
Adding a control object allows Qt to disconnect the connection automatically when that object is deleted. It does not matter in this case (your canvas is part of UI which is part of
this
), but in other situations it is a good thing to remember about (and costs nothing).