Using a lambda as a slot problem
-
I'm using last version of VS2019 and when I use a lambda as a slot in QTimer::singleShot() compiler give me follow error
no instance of overloaded function matches the argument list argument types are: (int, SwitchBlock , lambda []void ()->void)
although I made a similiar connection successfully in another class.
Here is the class
#pragma once #include "Inert.h" class SwitchBlock : public Inert { private: static bool pressed; int animation_counter; //textures QPixmap texture_spawning[11]; QPixmap texture_active[3]; QPixmap texture_smashed; bool spawning; bool active; public: SwitchBlock(QPoint position); static bool IsPressed() { return pressed; } virtual std::string name() { return "SwitchBlock"; } virtual void animate(); virtual void hit(Object* what, Direction fromDir); };
This is the method in which I tried to use the lambda as a slot
void SwitchBlock::hit(Object* what, Direction fromDir) { Mario* mario = dynamic_cast<Mario*>(what); if (mario && fromDir == UP) { active = false; collidable = false; Game::instance()->stopMusic(); pressed = true; Sounds::instance()->play("switch-hit"); QTimer::singleShot(200, this, [this] { pressed = false; }); } }
-
@Giuseppe97
QTimer::singleShot()
needs a QObject instance as receiver to work.
As far as I can see the is not the case with SwichtBlock?But you could use what, but the lambda will be executed in the thread of this instance:
QTimer::singleShot(200, what, [this]() { pressed = false; });
-
@Giuseppe97
well it's missing some parts, most importantly the parameter listQTimer::singleShot(200, this, [this]()->void { pressed = false; });
-
@J-Hilk
Thanks . I suppose I have to study better the syntax of lambdas. -
@Giuseppe97
maybe in this way you can avoid to passthis
QTimer::singleShot(200, this, [&pressed](){ pressed = false; });
-
@guerinoni
I have tried but compiler tells that in capture list SwitchBlock::pressed is not a variable. -
@Giuseppe97 said in Using a lambda as a slot problem:
@guerinoni
I have tried but compiler tells that in capture list SwitchBlock::pressed is not a variable.ok then just pass all by reference
[&]
-
@guerinoni
Capturing all by reference cause the initial error QTimer::singleShot': none of the 6 overloads could convert all the argument types -
@Giuseppe97 Did you try what @J-Hilk suggested?
-
@jsulm
Yes but it doesn't compile. I have marked the question as solved because for a moment the compiler didn't reject the lambda but when i rebuild the solution the problem was still there. I am also trying to figure out what's the problem by myself through a deep study of lambda syntax. -
@Giuseppe97 said in Using a lambda as a slot problem:
QTimer::singleShot(200, this, [this] { pressed = false; });
You have to add () to define the lambda function ==>
QTimer::singleShot(200, this, [this]() { pressed = false; });
Take a look at https://blog.feabhas.com/2014/03/demystifying-c-lambdas/ to get more details about Lambdas
-
@KroMignon
Thanks for the link but it doesn't compile.
-
@Giuseppe97
QTimer::singleShot()
needs a QObject instance as receiver to work.
As far as I can see the is not the case with SwichtBlock?But you could use what, but the lambda will be executed in the thread of this instance:
QTimer::singleShot(200, what, [this]() { pressed = false; });
-
@KroMignon
Thanks now it compile. Yes the problem was that SwitchBlock inherits by Inert which inherits by Object class which is a QGraphicsPixmapItem so the use of what doesn't resolve the problem . I could have used multiple inheritance so that SwitchBlock inherits both from QGraphicsPixmapItem and Qobject but I have choosen to move the call of singleShot static method to Game which inherits by QGraphicsView. -
@Giuseppe97 Oh sorry, I read you code too fast and I read void SwitchBlock::hit(QObject * what,...) instead of void SwitchBlock::hit(Object * what,...)!
But I this case, you could also use
qApp
as receiver, so lambda will run in main thread:Timer::singleShot(200, qApp, [this]() { pressed = false; });
-
@KroMignon
Ok thanks I will do this way since for the application (a level of Super Mario Bros 3 (NES)) I didn't use multiple threads . By the way this is my first "serious" project (for a university exam) and I am amazingly surprised of how many things I have learned since I have started.