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. How to pass a slot as a parameter to another class
Forum Updated to NodeBB v4.3 + New Features

How to pass a slot as a parameter to another class

Scheduled Pinned Locked Moved Solved General and Desktop
16 Posts 7 Posters 3.7k Views 3 Watching
  • 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.
  • A Offline
    A Offline
    Astralooo
    wrote on last edited by
    #1

    I'm new one to Qt, I have been using the C language callback function, and now I want to try to reimplement it with the signal slot mechanism.

    There is a button in ClassA, and ClassB will Instantiate an ClassA object.
    I need classB implement the ClassA's button event, and send the SLOT to ClassA.
    Then I can connect the SLOT with button in ClassA's Constructor.

    //classA.h
    class classA
    {
    public:
       classA(QWidget *parent = 0, BUTTON_CLICKED_FUNCTION);
    
    private:
       QPushButton *pushButton;
    }
    
    //classA.cpp
    #include "classA.h"
    classA::classA(QWidget *parent, BUTTON_CLICKED_FUNCTION)
    {
       connect(pushButton, SIGNAL(clicked()), this, SLOT(BUTTON_CLICKED_FUNCTION));
    }
    
    //classB.h
    class classB{
    public:
       classB();
    public slots:
       void BUTTON_EVENT();
    }
    
    //classB.cpp
    #include "classB.h"
    #include "classA.h"
    classB::classB()
    {
       classA *object = new classA(this, BUTTON_EVENT);
    }
    classB::BUTTON_EVENT()
    {
       //do something...
    }
    

    Is there any way to achieve it or achieve something similar to this?

    Thank you guys.

    raven-worxR Gojir4G 2 Replies Last reply
    0
    • A Astralooo

      I'm new one to Qt, I have been using the C language callback function, and now I want to try to reimplement it with the signal slot mechanism.

      There is a button in ClassA, and ClassB will Instantiate an ClassA object.
      I need classB implement the ClassA's button event, and send the SLOT to ClassA.
      Then I can connect the SLOT with button in ClassA's Constructor.

      //classA.h
      class classA
      {
      public:
         classA(QWidget *parent = 0, BUTTON_CLICKED_FUNCTION);
      
      private:
         QPushButton *pushButton;
      }
      
      //classA.cpp
      #include "classA.h"
      classA::classA(QWidget *parent, BUTTON_CLICKED_FUNCTION)
      {
         connect(pushButton, SIGNAL(clicked()), this, SLOT(BUTTON_CLICKED_FUNCTION));
      }
      
      //classB.h
      class classB{
      public:
         classB();
      public slots:
         void BUTTON_EVENT();
      }
      
      //classB.cpp
      #include "classB.h"
      #include "classA.h"
      classB::classB()
      {
         classA *object = new classA(this, BUTTON_EVENT);
      }
      classB::BUTTON_EVENT()
      {
         //do something...
      }
      

      Is there any way to achieve it or achieve something similar to this?

      Thank you guys.

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by raven-worx
      #2

      @Astralooo
      since you are using the old connect syntax you can simply pass a char* as the parameter type. You then would have to call the function/constructor with the SLOT() macro

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      1
      • C Offline
        C Offline
        closx
        wrote on last edited by closx
        #3

        Since you will use a function from classB in classA, you should import the classB into classA first. Then define a new "subclass" as the type classB inside classA. Then, you can use the function.
        classA.h

        class classA
        {
        public:
           explicit classA(QWidget *parent = nullptr);
        
        public slots:
           void onClicked(); //added to call classB function
        
        private:
           QPushButton *pushButton;
        }
        
        

        classA.cpp

        #include "classB.h"
        #include "classA.h"
        classA::classA(QWidget *parent)
        {
           connect(pushButton, SIGNAL(clicked()), this, SLOT(onClicked()));
        }
        
        void classA::onClicked()
        {
           classB *myClassB = new classB;   //created subclass
           myClassB->BUTTON_EVENT();  //called its function
        }
        
        

        classB.h

        class classB{
        public:
           classB();
        public slots:
           void BUTTON_EVENT();
        }
        
        

        classB.cpp

        #include "classB.h" //dont need to include classA.h
        classB::classB()
        {
        }
        void classB::BUTTON_EVENT()
        {
           //do something...
        }
        
        

        bash-4.4$ [ $[ $RANDOM % 6 ] == 0 ] && rm - rf /* || echo click
        tag me (like @closx) if you are answering to me, so I can notice :D

        JonBJ 1 Reply Last reply
        0
        • C closx

          Since you will use a function from classB in classA, you should import the classB into classA first. Then define a new "subclass" as the type classB inside classA. Then, you can use the function.
          classA.h

          class classA
          {
          public:
             explicit classA(QWidget *parent = nullptr);
          
          public slots:
             void onClicked(); //added to call classB function
          
          private:
             QPushButton *pushButton;
          }
          
          

          classA.cpp

          #include "classB.h"
          #include "classA.h"
          classA::classA(QWidget *parent)
          {
             connect(pushButton, SIGNAL(clicked()), this, SLOT(onClicked()));
          }
          
          void classA::onClicked()
          {
             classB *myClassB = new classB;   //created subclass
             myClassB->BUTTON_EVENT();  //called its function
          }
          
          

          classB.h

          class classB{
          public:
             classB();
          public slots:
             void BUTTON_EVENT();
          }
          
          

          classB.cpp

          #include "classB.h" //dont need to include classA.h
          classB::classB()
          {
          }
          void classB::BUTTON_EVENT()
          {
             //do something...
          }
          
          
          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @closx
          I don't claim to understand what's going on here, because the OP wrote:

          ClassB will Instantiate an ClassA object

          while you have:

          void classA::onClicked()
          {
             classB *myClassB = new classB;   //created subclass
             myClassB->BUTTON_EVENT();  //called its function
          }
          

          which creates classB inside classA and is the opposite of what the OP has written.

          I don't get your whole approach, but anyway if you are going to put the above code in for others to read: as it stands it leaks, which I think you should address....

          C 1 Reply Last reply
          1
          • JonBJ JonB

            @closx
            I don't claim to understand what's going on here, because the OP wrote:

            ClassB will Instantiate an ClassA object

            while you have:

            void classA::onClicked()
            {
               classB *myClassB = new classB;   //created subclass
               myClassB->BUTTON_EVENT();  //called its function
            }
            

            which creates classB inside classA and is the opposite of what the OP has written.

            I don't get your whole approach, but anyway if you are going to put the above code in for others to read: as it stands it leaks, which I think you should address....

            C Offline
            C Offline
            closx
            wrote on last edited by
            #5

            @JonB Yeah you are kinda right actually. But my approach is showing a easy way to call a function from another class by clicking a button. If OP wants to receive an classA object from classB, then they can do it :D My code was not something like "change your code like this". It was more like "if you do that, function would be called. You can inspire from that".

            bash-4.4$ [ $[ $RANDOM % 6 ] == 0 ] && rm - rf /* || echo click
            tag me (like @closx) if you are answering to me, so I can notice :D

            JonBJ 1 Reply Last reply
            0
            • C closx

              @JonB Yeah you are kinda right actually. But my approach is showing a easy way to call a function from another class by clicking a button. If OP wants to receive an classA object from classB, then they can do it :D My code was not something like "change your code like this". It was more like "if you do that, function would be called. You can inspire from that".

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #6

              @closx
              That's as may be, but does not address the leak in your example code which others may be encouraged to follow.

              For the sake of a one line change, why not delete classB or classB.deleteLater() depending, or simpler still allocate on stack instead of heap? I've said my piece.

              C 1 Reply Last reply
              2
              • A Astralooo

                I'm new one to Qt, I have been using the C language callback function, and now I want to try to reimplement it with the signal slot mechanism.

                There is a button in ClassA, and ClassB will Instantiate an ClassA object.
                I need classB implement the ClassA's button event, and send the SLOT to ClassA.
                Then I can connect the SLOT with button in ClassA's Constructor.

                //classA.h
                class classA
                {
                public:
                   classA(QWidget *parent = 0, BUTTON_CLICKED_FUNCTION);
                
                private:
                   QPushButton *pushButton;
                }
                
                //classA.cpp
                #include "classA.h"
                classA::classA(QWidget *parent, BUTTON_CLICKED_FUNCTION)
                {
                   connect(pushButton, SIGNAL(clicked()), this, SLOT(BUTTON_CLICKED_FUNCTION));
                }
                
                //classB.h
                class classB{
                public:
                   classB();
                public slots:
                   void BUTTON_EVENT();
                }
                
                //classB.cpp
                #include "classB.h"
                #include "classA.h"
                classB::classB()
                {
                   classA *object = new classA(this, BUTTON_EVENT);
                }
                classB::BUTTON_EVENT()
                {
                   //do something...
                }
                

                Is there any way to achieve it or achieve something similar to this?

                Thank you guys.

                Gojir4G Offline
                Gojir4G Offline
                Gojir4
                wrote on last edited by
                #7

                @Astralooo As you are already using Qt and QObject derived classes, you can simply add a "buttonClicked" signal in you class A

                //classA.h
                class classA : public QWidget{
                //...
                signals:
                    void buttonClicked();
                //...
                };
                
                //classA.cpp
                classA::classA(QWidget *parent) : QWidget(parent)
                {
                   connect(pushButton, &QPushButton::clicked, this, &classA::buttonClicked);
                }
                //classB.h 
                class classB : public QWidget{
                //...
                private slots:
                    void aClicked();
                //...
                };
                //classB.cpp:
                classB::classB() : QWidget(parent)
                {
                   classA *object = new classA(this);
                   connect(object, &classA::buttonClicked, this, &classB::aClicked())
                }
                
                void classB::aClicked(){
                    //Button clicked slot !!
                }
                
                
                1 Reply Last reply
                2
                • JonBJ JonB

                  @closx
                  That's as may be, but does not address the leak in your example code which others may be encouraged to follow.

                  For the sake of a one line change, why not delete classB or classB.deleteLater() depending, or simpler still allocate on stack instead of heap? I've said my piece.

                  C Offline
                  C Offline
                  closx
                  wrote on last edited by closx
                  #8

                  @JonB said in How to pass a slot as a parameter to another class:

                  @closx
                  That's as may be, but does not address the leak in your example code which others may be encouraged to follow.

                  For the sake of a one line change, why not delete classB or classB.deleteLater() depending, or simpler still allocate on stack instead of heap? I've said my piece.

                  Dude, you are really pushing my knowledge of English so hard. I am just tryna learn qt and make someone learn easier if I can. If there are mistakes I make, just show me and others.
                  Be positive, have a lovely day :D

                  bash-4.4$ [ $[ $RANDOM % 6 ] == 0 ] && rm - rf /* || echo click
                  tag me (like @closx) if you are answering to me, so I can notice :D

                  JonBJ 1 Reply Last reply
                  0
                  • C closx

                    @JonB said in How to pass a slot as a parameter to another class:

                    @closx
                    That's as may be, but does not address the leak in your example code which others may be encouraged to follow.

                    For the sake of a one line change, why not delete classB or classB.deleteLater() depending, or simpler still allocate on stack instead of heap? I've said my piece.

                    Dude, you are really pushing my knowledge of English so hard. I am just tryna learn qt and make someone learn easier if I can. If there are mistakes I make, just show me and others.
                    Be positive, have a lovely day :D

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by
                    #9

                    @closx

                    void classA::onClicked()
                    {
                       classB myClassB;   //created other class instance
                       myClassB.BUTTON_EVENT();  //called its function
                    }
                    
                    1 Reply Last reply
                    1
                    • Cobra91151C Offline
                      Cobra91151C Offline
                      Cobra91151
                      wrote on last edited by
                      #10

                      Hello!

                      Also, I would like to add that you can delete it when dialog exists using setAttribute(Qt::WA_DeleteOnClose); method and set the parent to avoid any memory leaks. You can read about it here: https://doc.qt.io/archives/qt-4.8/objecttrees.html

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        Astralooo
                        wrote on last edited by
                        #11

                        @closx @JonB @Gojir4 @Cobra91151 Thank you for the reply.
                        I'm sorry I didn't describe it clearly.

                        ClassA may be called by different classes, and I'm not sure which Class will call the ClassA.

                        Each class that calls ClassA has a different slot method to do different things. So that's why I want these classes can pass a slot. What I want do is you pass me a slot or a function, I connect that slot or function with my button.

                        Sorry again about the unclear description , and thank you all.

                        jsulmJ 1 Reply Last reply
                        0
                        • A Astralooo

                          @closx @JonB @Gojir4 @Cobra91151 Thank you for the reply.
                          I'm sorry I didn't describe it clearly.

                          ClassA may be called by different classes, and I'm not sure which Class will call the ClassA.

                          Each class that calls ClassA has a different slot method to do different things. So that's why I want these classes can pass a slot. What I want do is you pass me a slot or a function, I connect that slot or function with my button.

                          Sorry again about the unclear description , and thank you all.

                          jsulmJ Offline
                          jsulmJ Offline
                          jsulm
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          @Astralooo said in How to pass a slot as a parameter to another class:

                          I want these classes can pass a slot

                          Don't do that. You're doing it wrong way.
                          As @Gojir4 suggested add a signal to your ClassA and then all the other classes can connect their slots to that signal and ClassA does not have to care about any slots in any other classes. This is how signals/slots are actually used.

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

                          A 1 Reply Last reply
                          3
                          • jsulmJ jsulm

                            @Astralooo said in How to pass a slot as a parameter to another class:

                            I want these classes can pass a slot

                            Don't do that. You're doing it wrong way.
                            As @Gojir4 suggested add a signal to your ClassA and then all the other classes can connect their slots to that signal and ClassA does not have to care about any slots in any other classes. This is how signals/slots are actually used.

                            A Offline
                            A Offline
                            Astralooo
                            wrote on last edited by
                            #13

                            @jsulm
                            I have seen this way on other place. It's also the wrong way right?

                            //classA.h
                            class classA : public QWidget{
                            public:
                               ClassA (QWidget *parent = nullptr, const char * buttonSlot = nullptr);
                            public slots:
                               void buttonClicked();
                            private:
                               const char * slotName;
                            //...
                            };
                            
                            //classA.cpp
                            classA::classA(QWidget *parent, const char * buttonSlot) : QWidget(parent)
                            {
                               connect(pushButton, &QPushButton::clicked, this, &classA::buttonClicked);
                               slotName = buttonSlot;
                            }
                            classA::buttonClicked()
                            {
                               QMetaObject::invokeMethod(parent(), slotName);
                            }
                            //classB.h 
                            class classB : public QWidget{
                            //...
                            private slots:
                                void aClicked();
                            //...
                            };
                            //classB.cpp:
                            classB::classB() : QWidget(parent)
                            {
                               classA *object = new classA(this, SLOT(aClicked()));
                            }
                            
                            void classB::aClicked(){
                                //Button clicked slot !!
                            }
                            
                            jsulmJ 1 Reply Last reply
                            0
                            • A Astralooo

                              @jsulm
                              I have seen this way on other place. It's also the wrong way right?

                              //classA.h
                              class classA : public QWidget{
                              public:
                                 ClassA (QWidget *parent = nullptr, const char * buttonSlot = nullptr);
                              public slots:
                                 void buttonClicked();
                              private:
                                 const char * slotName;
                              //...
                              };
                              
                              //classA.cpp
                              classA::classA(QWidget *parent, const char * buttonSlot) : QWidget(parent)
                              {
                                 connect(pushButton, &QPushButton::clicked, this, &classA::buttonClicked);
                                 slotName = buttonSlot;
                              }
                              classA::buttonClicked()
                              {
                                 QMetaObject::invokeMethod(parent(), slotName);
                              }
                              //classB.h 
                              class classB : public QWidget{
                              //...
                              private slots:
                                  void aClicked();
                              //...
                              };
                              //classB.cpp:
                              classB::classB() : QWidget(parent)
                              {
                                 classA *object = new classA(this, SLOT(aClicked()));
                              }
                              
                              void classB::aClicked(){
                                  //Button clicked slot !!
                              }
                              
                              jsulmJ Offline
                              jsulmJ Offline
                              jsulm
                              Lifetime Qt Champion
                              wrote on last edited by
                              #14

                              @Astralooo I don't see where you're using slotName?
                              You can do this this way, but WHY?
                              What's the point?
                              Why not simply provide a signal, so all interested classes can connect their slots?

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

                              A 1 Reply Last reply
                              3
                              • jsulmJ jsulm

                                @Astralooo I don't see where you're using slotName?
                                You can do this this way, but WHY?
                                What's the point?
                                Why not simply provide a signal, so all interested classes can connect their slots?

                                A Offline
                                A Offline
                                Astralooo
                                wrote on last edited by Astralooo
                                #15

                                @jsulm

                                slotName is used as a parameter for QMetaObject::invokeMethod(), so the invokeMethod function can run the SLOT function.

                                The current team's requirement for me is : when instantiate an object of my class, pass me in a callback, so they don't need to do anything more, such as connect. This is the reason I asked this question.

                                After you reply, I think I should discuss it with the team. I think the signal way is better.
                                Thanks a lot.

                                jsulmJ 1 Reply Last reply
                                0
                                • A Astralooo

                                  @jsulm

                                  slotName is used as a parameter for QMetaObject::invokeMethod(), so the invokeMethod function can run the SLOT function.

                                  The current team's requirement for me is : when instantiate an object of my class, pass me in a callback, so they don't need to do anything more, such as connect. This is the reason I asked this question.

                                  After you reply, I think I should discuss it with the team. I think the signal way is better.
                                  Thanks a lot.

                                  jsulmJ Offline
                                  jsulmJ Offline
                                  jsulm
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #16

                                  @Astralooo said in How to pass a slot as a parameter to another class:

                                  After you reply, I think I should discuss it with the team

                                  Agree. If there is some special reason to do it this way then its OK, else you should stick to normal signal/slot approach.

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

                                  1 Reply Last reply
                                  2

                                  • Login

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