Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Using a lambda as a slot problem

Using a lambda as a slot problem

Scheduled Pinned Locked Moved Solved General and Desktop
15 Posts 5 Posters 1.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    Giuseppe97
    wrote on 24 Feb 2020, 11:23 last edited by
    #5

    @guerinoni
    I have tried but compiler tells that in capture list SwitchBlock::pressed is not a variable.

    G 1 Reply Last reply 24 Feb 2020, 11:24
    0
    • G Giuseppe97
      24 Feb 2020, 11:23

      @guerinoni
      I have tried but compiler tells that in capture list SwitchBlock::pressed is not a variable.

      G Offline
      G Offline
      guerinoni
      wrote on 24 Feb 2020, 11:24 last edited by
      #6

      @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 [&]

      1 Reply Last reply
      0
      • G Offline
        G Offline
        Giuseppe97
        wrote on 24 Feb 2020, 11:33 last edited by
        #7

        @guerinoni
        Capturing all by reference cause the initial error QTimer::singleShot': none of the 6 overloads could convert all the argument types

        J 1 Reply Last reply 24 Feb 2020, 12:32
        0
        • G Giuseppe97
          24 Feb 2020, 11:33

          @guerinoni
          Capturing all by reference cause the initial error QTimer::singleShot': none of the 6 overloads could convert all the argument types

          J Offline
          J Offline
          jsulm
          Lifetime Qt Champion
          wrote on 24 Feb 2020, 12:32 last edited by
          #8

          @Giuseppe97 Did you try what @J-Hilk suggested?

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • G Offline
            G Offline
            Giuseppe97
            wrote on 24 Feb 2020, 15:57 last edited by Giuseppe97
            #9

            @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.

            1 Reply Last reply
            0
            • G Giuseppe97
              24 Feb 2020, 11:03

              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; });
              
              
              	}
              }
              
              K Offline
              K Offline
              KroMignon
              wrote on 24 Feb 2020, 16:13 last edited by KroMignon
              #10

              @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

              It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

              1 Reply Last reply
              1
              • G Offline
                G Offline
                Giuseppe97
                wrote on 24 Feb 2020, 16:18 last edited by Giuseppe97
                #11

                @KroMignon
                Thanks for the link but it doesn't compile.
                UUUpng.png

                K 1 Reply Last reply 24 Feb 2020, 16:32
                0
                • G Giuseppe97
                  24 Feb 2020, 16:18

                  @KroMignon
                  Thanks for the link but it doesn't compile.
                  UUUpng.png

                  K Offline
                  K Offline
                  KroMignon
                  wrote on 24 Feb 2020, 16:32 last edited by KroMignon
                  #12

                  @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; });
                  

                  It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                  1 Reply Last reply
                  1
                  • G Offline
                    G Offline
                    Giuseppe97
                    wrote on 24 Feb 2020, 16:36 last edited by Giuseppe97
                    #13

                    @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.

                    K 1 Reply Last reply 24 Feb 2020, 16:44
                    0
                    • G Giuseppe97
                      24 Feb 2020, 16:36

                      @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.

                      K Offline
                      K Offline
                      KroMignon
                      wrote on 24 Feb 2020, 16:44 last edited by KroMignon
                      #14

                      @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; });
                      

                      It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                      1 Reply Last reply
                      0
                      • G Offline
                        G Offline
                        Giuseppe97
                        wrote on 24 Feb 2020, 16:58 last edited by
                        #15

                        @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.

                        1 Reply Last reply
                        1

                        14/15

                        24 Feb 2020, 16:44

                        • Login

                        • Login or register to search.
                        14 out of 15
                        • First post
                          14/15
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved