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. Pass two arguments to a slot
Qt 6.11 is out! See what's new in the release blog

Pass two arguments to a slot

Scheduled Pinned Locked Moved Solved General and Desktop
26 Posts 6 Posters 16.7k Views 2 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.
  • N Nouriemm

    Hey there,
    Why don't you use a vector instead?

    H Offline
    H Offline
    Helson
    wrote on last edited by
    #8

    @Nouriemm

    Can you explain me a little bit?

    1 Reply Last reply
    0
    • kshegunovK kshegunov

      @Helson
      Hello,
      Slots are regular functions, so you can call them as such. For example:

      class ExampleClass : public QObject
      {
         Q_OBJECT
      signals:
          void myComboSignal(int, int);
      
      public slots:
          ExampleClass()
               : additionalParameter(100)
          {
              combo = new QComboBox();
              QObject::connect(combo, SIGNAL(currentIndexChanged(int)), this, SLOT(handleComboIndex(int)));
          }
      
          void handleComboIndex(int index)
          {
               comboBoxCourseLoadValues(index, additionalParameter); // < Call the slot directly
               // AND/OR
               emit myComboSignal(index, additionalParameter); // < Emit your own signal that you can connect to another slot
          }
      
          void comboBoxCourseLoadValues(int, int);
      
      private:
          int additionalParameter;
          QComboBox * combo;
      }
      

      Kind regards.

      H Offline
      H Offline
      Helson
      wrote on last edited by Helson
      #9

      @kshegunov

      Thanks for you elucidation.

      But I dont know how I can get "additionalParameter" into handleComboIndex() without use it's in class construct.
      This parameter value is obtained in runtime.

      I'm using QT 4.8 version.

      My best regards!

      K 1 Reply Last reply
      0
      • M Offline
        M Offline
        mike_student
        wrote on last edited by
        #10

        Hello,
        you can use other way to declare SIGNAL & SLOT combination with

        connect(ComboBox, &currentIndexChanged, this, &comboBoxCourseLoadValues);
        

        and then you can use as many parameters as you want for comboBoxCourseLoadValues.

        Kind regards.

        H 1 Reply Last reply
        0
        • M mike_student

          Hello,
          you can use other way to declare SIGNAL & SLOT combination with

          connect(ComboBox, &currentIndexChanged, this, &comboBoxCourseLoadValues);
          

          and then you can use as many parameters as you want for comboBoxCourseLoadValues.

          Kind regards.

          H Offline
          H Offline
          Helson
          wrote on last edited by
          #11

          @mike_student

          I try this, but the slot is never called :/

          K 1 Reply Last reply
          0
          • H Helson

            @kshegunov

            Thanks for you elucidation.

            But I dont know how I can get "additionalParameter" into handleComboIndex() without use it's in class construct.
            This parameter value is obtained in runtime.

            I'm using QT 4.8 version.

            My best regards!

            K Offline
            K Offline
            koahnig
            wrote on last edited by koahnig
            #12

            @Helson said:

            @kshegunov

            Thanks for you elucidation.

            But I dont know how I can get "additionalParameter" into handleComboIndex() without use it's in class construct.
            This parameter value is obtained in runtime.

            I'm using QT 4.8 version.

            My best regards!

            as explained above by @kshegunov there is no direct way to connect with single argument signal to a double argument slot. The problem could be how the SW shall decide what the second arguments are.

            There are more elaborate ways to handle, but I think it is much simpler for you at the time to add another slot routine with only one argument. This may be connected to the combobox. Within this single argument slot you simply call your double argument slot. You can use any slot as a member function, because it simply is.

            Vote the answer(s) that helped you to solve your issue(s)

            H 1 Reply Last reply
            1
            • H Helson

              @mike_student

              I try this, but the slot is never called :/

              K Offline
              K Offline
              koahnig
              wrote on last edited by koahnig
              #13

              @Helson said:

              I try this, but the slot is never called :/

              Because you are still using Qt 4.8. To my knowledge it has been added to Qt 5.3 or higher.

              [edit: koahnig]

              Vote the answer(s) that helped you to solve your issue(s)

              1 Reply Last reply
              0
              • K koahnig

                @Helson said:

                @kshegunov

                Thanks for you elucidation.

                But I dont know how I can get "additionalParameter" into handleComboIndex() without use it's in class construct.
                This parameter value is obtained in runtime.

                I'm using QT 4.8 version.

                My best regards!

                as explained above by @kshegunov there is no direct way to connect with single argument signal to a double argument slot. The problem could be how the SW shall decide what the second arguments are.

                There are more elaborate ways to handle, but I think it is much simpler for you at the time to add another slot routine with only one argument. This may be connected to the combobox. Within this single argument slot you simply call your double argument slot. You can use any slot as a member function, because it simply is.

                H Offline
                H Offline
                Helson
                wrote on last edited by Helson
                #14

                @koahnig

                How I can pass the parameter inside to the second slot ?

                void handleComboIndex(int index)
                  {
                       comboBoxCourseLoadValues(index, additionalParameter);  //additionalParameter is unknow here 
                       // AND/OR
                       emit myComboSignal(index, additionalParameter); // 
                  }
                

                additionalParameter is obtained in another method.
                So I want to spend the second parameter in the slot.

                Please.

                K 1 Reply Last reply
                0
                • H Helson

                  @koahnig

                  How I can pass the parameter inside to the second slot ?

                  void handleComboIndex(int index)
                    {
                         comboBoxCourseLoadValues(index, additionalParameter);  //additionalParameter is unknow here 
                         // AND/OR
                         emit myComboSignal(index, additionalParameter); // 
                    }
                  

                  additionalParameter is obtained in another method.
                  So I want to spend the second parameter in the slot.

                  Please.

                  K Offline
                  K Offline
                  koahnig
                  wrote on last edited by
                  #15

                  @Helson

                  Basically the first possibility. As described a slot routine is basically an extended member function and you still can use it as member function.

                  You can handle it also through a signal (your emit there) plus an additional connect to the new slot, but that seems ackward here.

                  Where should your parameter come from?
                  Your combobox will not know either. If you know it outside sometwhere you have to pass it to the object beforehand. signal-slots do some "magic", but crystal ball reading is not part of it ;)

                  Vote the answer(s) that helped you to solve your issue(s)

                  H 1 Reply Last reply
                  0
                  • K koahnig

                    @Helson

                    Basically the first possibility. As described a slot routine is basically an extended member function and you still can use it as member function.

                    You can handle it also through a signal (your emit there) plus an additional connect to the new slot, but that seems ackward here.

                    Where should your parameter come from?
                    Your combobox will not know either. If you know it outside sometwhere you have to pass it to the object beforehand. signal-slots do some "magic", but crystal ball reading is not part of it ;)

                    H Offline
                    H Offline
                    Helson
                    wrote on last edited by Helson
                    #16

                    @koahnig

                    Same .cpp file.

                    void ClassOne::execute()
                    {
                        QVector<QString> myArray;
                    
                        DialogClass dlg;
                    
                        if(QDialog::Accepted == dlg.exec())
                        {
                    		for(int i = 0; i < 10 ; i++){
                    			other = getInfo();
                    			myArray.push_back(other);
                    		}
                    		 connect(dlg.ComboBox, SIGNAL(currentIndexChanged(int)), &dlg,  mySlot(int)));	
                             dlg.comboBox(anotherArray);	 // This fill the combobox
                        }
                    }
                    
                    void DialogClass::mySlot(int index){
                    //I Need the myArray here.
                    }
                    
                    K 1 Reply Last reply
                    0
                    • N Offline
                      N Offline
                      Nouriemm
                      wrote on last edited by Nouriemm
                      #17

                      As I said the easiest way is to use a vector but keep in mind it is not a direct solution.
                      First you have to send the currentIndexChanged(int) to a slot that accepts (int) as-well, like this:
                      connect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(comboBoxCourseLoadValues(int)));
                      But the Slot is capable of remembering the value of emitted signal until it receives another call.
                      As soon as the slot receives two INTs(what you are looking for) you can do what ever you want with it or emit another signal from there to another slot which accepts (int,int).
                      Here is the code:

                      void MainWindow::comboBoxCourseLoadValues(int p) {
                      static QVector<int> vec;
                      vec.push_front(p);
                      if(vec.size()>1){
                          /*Here you have got 2 INTs.*/
                          /*And you can do what ever you want with them. Eg:Send a new Signal(int,int)*/
                          /*but make sure to not send the address of them somewhere else AT ALL*/
                          /*becuase we are going to clear the vector Now*/
                          qDebug()<<vec.at(0)<<vec.at(1);  //for viewing the out put result
                           vec.clear();
                         }
                      

                      }

                      H 1 Reply Last reply
                      1
                      • H Helson

                        @koahnig

                        Same .cpp file.

                        void ClassOne::execute()
                        {
                            QVector<QString> myArray;
                        
                            DialogClass dlg;
                        
                            if(QDialog::Accepted == dlg.exec())
                            {
                        		for(int i = 0; i < 10 ; i++){
                        			other = getInfo();
                        			myArray.push_back(other);
                        		}
                        		 connect(dlg.ComboBox, SIGNAL(currentIndexChanged(int)), &dlg,  mySlot(int)));	
                                 dlg.comboBox(anotherArray);	 // This fill the combobox
                            }
                        }
                        
                        void DialogClass::mySlot(int index){
                        //I Need the myArray here.
                        }
                        
                        K Offline
                        K Offline
                        koahnig
                        wrote on last edited by koahnig
                        #18

                        @Helson

                        I did not find the class definition for DialogClass above. However, it may look similar like:

                        class Dialog : public QObject 
                        {
                        ...
                        public:
                             QComboBox ComboBox;
                        ...
                        public slots: 
                            void mySlot(int index);
                        ...
                        };
                        

                        What hinders you to add the second array?

                         class Dialog : public QObject 
                        {
                        ...
                            QVector<QString> mArray;
                        public:
                            QComboBox ComboBox;
                        ...
                             void setSecondArray ( const QVector<QString> & array )
                             {
                                   mArray = array;
                             }
                         public slots: 
                        void mySlot(int index);
                        ...
                        };
                        
                        void DialogClass::mySlot(int index){
                               do_something_with = mArray.at(index); //I Need the myArray here.
                        }
                        

                        Vote the answer(s) that helped you to solve your issue(s)

                        H 1 Reply Last reply
                        1
                        • N Nouriemm

                          As I said the easiest way is to use a vector but keep in mind it is not a direct solution.
                          First you have to send the currentIndexChanged(int) to a slot that accepts (int) as-well, like this:
                          connect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(comboBoxCourseLoadValues(int)));
                          But the Slot is capable of remembering the value of emitted signal until it receives another call.
                          As soon as the slot receives two INTs(what you are looking for) you can do what ever you want with it or emit another signal from there to another slot which accepts (int,int).
                          Here is the code:

                          void MainWindow::comboBoxCourseLoadValues(int p) {
                          static QVector<int> vec;
                          vec.push_front(p);
                          if(vec.size()>1){
                              /*Here you have got 2 INTs.*/
                              /*And you can do what ever you want with them. Eg:Send a new Signal(int,int)*/
                              /*but make sure to not send the address of them somewhere else AT ALL*/
                              /*becuase we are going to clear the vector Now*/
                              qDebug()<<vec.at(0)<<vec.at(1);  //for viewing the out put result
                               vec.clear();
                             }
                          

                          }

                          H Offline
                          H Offline
                          Helson
                          wrote on last edited by
                          #19

                          @Nouriemm
                          Ohh Thanks for this explanation, but in this case I need a parameter of another type:

                          connect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(comboBoxCourseLoadValues(int, QVector)));

                          But I like your explanation, I learned too much about signals.

                          1 Reply Last reply
                          0
                          • K koahnig

                            @Helson

                            I did not find the class definition for DialogClass above. However, it may look similar like:

                            class Dialog : public QObject 
                            {
                            ...
                            public:
                                 QComboBox ComboBox;
                            ...
                            public slots: 
                                void mySlot(int index);
                            ...
                            };
                            

                            What hinders you to add the second array?

                             class Dialog : public QObject 
                            {
                            ...
                                QVector<QString> mArray;
                            public:
                                QComboBox ComboBox;
                            ...
                                 void setSecondArray ( const QVector<QString> & array )
                                 {
                                       mArray = array;
                                 }
                             public slots: 
                            void mySlot(int index);
                            ...
                            };
                            
                            void DialogClass::mySlot(int index){
                                   do_something_with = mArray.at(index); //I Need the myArray here.
                            }
                            
                            H Offline
                            H Offline
                            Helson
                            wrote on last edited by
                            #20

                            @koahnig

                            The @mrjj give me a solution with pointers in another topic:
                            https://forum.qt.io/topic/62427/get-a-array-inside-slot

                            But what you say is very useful.

                             QVector<QString> mArray; ///is in another class definition
                            

                            Why the code below is in the class definition? When it's called? How I can do learn more about it?

                            void setSecondArray ( const QVector<QString> & array )
                            {
                                       mArray = array;
                            }
                            
                            K kshegunovK 2 Replies Last reply
                            0
                            • H Helson

                              @koahnig

                              The @mrjj give me a solution with pointers in another topic:
                              https://forum.qt.io/topic/62427/get-a-array-inside-slot

                              But what you say is very useful.

                               QVector<QString> mArray; ///is in another class definition
                              

                              Why the code below is in the class definition? When it's called? How I can do learn more about it?

                              void setSecondArray ( const QVector<QString> & array )
                              {
                                         mArray = array;
                              }
                              
                              K Offline
                              K Offline
                              koahnig
                              wrote on last edited by
                              #21

                              @Helson said:

                              Why the code below is in the class definition? When it's called? How I can do learn more about it?

                              void setSecondArray ( const QVector<QString> & array )
                              {
                              mArray = array;
                              }

                              That is basically inline code. As you might have noted is the array in my definition in the private section. Therefore, is somewhat secured, because not diretly accessible. With the inline definition the code section will be introduced directly whereever you use. It spares the overhead of calling a member function.
                              It has ups and downs and should be used only for short sections of code. Here is a link to an article

                              I seemed to remember that you noted a deadline. Therefore "kis"="keep it simple".
                              I looked at @mrjj code you linked. As far as I saw you cannot use it. You seem to use the original signals of QComboBox and that gives you an index for the current line. To make out of int index a complete array with other information would be magic.

                              Vote the answer(s) that helped you to solve your issue(s)

                              1 Reply Last reply
                              1
                              • H Helson

                                @koahnig

                                The @mrjj give me a solution with pointers in another topic:
                                https://forum.qt.io/topic/62427/get-a-array-inside-slot

                                But what you say is very useful.

                                 QVector<QString> mArray; ///is in another class definition
                                

                                Why the code below is in the class definition? When it's called? How I can do learn more about it?

                                void setSecondArray ( const QVector<QString> & array )
                                {
                                           mArray = array;
                                }
                                
                                kshegunovK Offline
                                kshegunovK Offline
                                kshegunov
                                Moderators
                                wrote on last edited by
                                #22

                                @Helson
                                Hello,
                                I'm a bit slow to respond these days, and have little to contribute to @koahnig's excellent points. I would advise against @Nouriemm's suggestion though only because of the unneeded use of static variables. While here it's not such a problem (since GUI objects are not reentrant anyway), in many cases using static variables like this:

                                void MainWindow::comboBoxCourseLoadValues(int p)
                                {
                                    static QVector<int> vec;
                                    ...
                                }
                                

                                can get you a lot of headaches ... especially when order of construction/destruction is important.

                                Kind regards.

                                Read and abide by the Qt Code of Conduct

                                N 1 Reply Last reply
                                1
                                • H Offline
                                  H Offline
                                  Helson
                                  wrote on last edited by
                                  #23

                                  @koahnig
                                  @kshegunov
                                  @Nouriemm

                                  I could learn a bit of QT and C++ throught the tips and advice.
                                  I hope one day contribute to the forum too.

                                  Thanks for the help all!

                                  1 Reply Last reply
                                  0
                                  • kshegunovK kshegunov

                                    @Helson
                                    Hello,
                                    I'm a bit slow to respond these days, and have little to contribute to @koahnig's excellent points. I would advise against @Nouriemm's suggestion though only because of the unneeded use of static variables. While here it's not such a problem (since GUI objects are not reentrant anyway), in many cases using static variables like this:

                                    void MainWindow::comboBoxCourseLoadValues(int p)
                                    {
                                        static QVector<int> vec;
                                        ...
                                    }
                                    

                                    can get you a lot of headaches ... especially when order of construction/destruction is important.

                                    Kind regards.

                                    N Offline
                                    N Offline
                                    Nouriemm
                                    wrote on last edited by
                                    #24

                                    @kshegunov
                                    Hey there,
                                    I know static variables are really fearful for the vast majority of programmers.
                                    But in my case it is not really as bad as it looks like and I don't think it makes any trouble in this case again.
                                    Plus All I was trying to do was to demonstrate my solution in a small piece of code which of-course can be implemented in hundreds of other ways and this is the part which I call it the art of programming.
                                    Cheers All

                                    kshegunovK 1 Reply Last reply
                                    0
                                    • N Nouriemm

                                      @kshegunov
                                      Hey there,
                                      I know static variables are really fearful for the vast majority of programmers.
                                      But in my case it is not really as bad as it looks like and I don't think it makes any trouble in this case again.
                                      Plus All I was trying to do was to demonstrate my solution in a small piece of code which of-course can be implemented in hundreds of other ways and this is the part which I call it the art of programming.
                                      Cheers All

                                      kshegunovK Offline
                                      kshegunovK Offline
                                      kshegunov
                                      Moderators
                                      wrote on last edited by kshegunov
                                      #25

                                      @Nouriemm
                                      Hello,
                                      I hope you're not taking it personally, I certainly wasn't trying to undermine your effort. As you can see I've noted that in this particular case your suggested solution is as good as any, I was only pointing out potential pitfalls that could occur in more involved cases. While static variables are in no way fearsome, a good practice is to avoid them if possible, and not because you're scared or don't know how to handle them, but because of their nasty side effects that one should always be keeping in mind. Opaque pointers are also usable, but I'm guessing you're not passing your objects around through void * just because you can, are you?

                                      Statics, globals and singletons (which are basically the same thing) have the nasty side effect of promoting interdependence between components and you have to take special measures when order of construction/destruction is important. On top of that, they, because such is their nature, are breaking reentrancy and you have to take special steps to work around it. Consider the following very simple example:

                                      class A
                                      {
                                          A() {}
                                          void acquireGlobalResource()  {}
                                      };
                                      
                                      A * a = new A();
                                      
                                      class B
                                      {
                                          B()
                                          {
                                              a->acquireGlobalResource();
                                          }
                                      };
                                      
                                      B b;
                                      
                                      int main()
                                      {
                                          // ...
                                      }
                                      

                                      Now, the question is, can you guarantee that a will be initialized before b, so when the constructor of the class B runs you get a valid reference?

                                      Kind regards.

                                      Read and abide by the Qt Code of Conduct

                                      N 1 Reply Last reply
                                      0
                                      • kshegunovK kshegunov

                                        @Nouriemm
                                        Hello,
                                        I hope you're not taking it personally, I certainly wasn't trying to undermine your effort. As you can see I've noted that in this particular case your suggested solution is as good as any, I was only pointing out potential pitfalls that could occur in more involved cases. While static variables are in no way fearsome, a good practice is to avoid them if possible, and not because you're scared or don't know how to handle them, but because of their nasty side effects that one should always be keeping in mind. Opaque pointers are also usable, but I'm guessing you're not passing your objects around through void * just because you can, are you?

                                        Statics, globals and singletons (which are basically the same thing) have the nasty side effect of promoting interdependence between components and you have to take special measures when order of construction/destruction is important. On top of that, they, because such is their nature, are breaking reentrancy and you have to take special steps to work around it. Consider the following very simple example:

                                        class A
                                        {
                                            A() {}
                                            void acquireGlobalResource()  {}
                                        };
                                        
                                        A * a = new A();
                                        
                                        class B
                                        {
                                            B()
                                            {
                                                a->acquireGlobalResource();
                                            }
                                        };
                                        
                                        B b;
                                        
                                        int main()
                                        {
                                            // ...
                                        }
                                        

                                        Now, the question is, can you guarantee that a will be initialized before b, so when the constructor of the class B runs you get a valid reference?

                                        Kind regards.

                                        N Offline
                                        N Offline
                                        Nouriemm
                                        wrote on last edited by
                                        #26

                                        @kshegunov
                                        First let me clear that I am not the advocate of static variables. Honestly, I try to avoid them as much as it is possible. All I was trying to do, again, was to demonstrate a solution not an absolute answer. In my opinion the best way to demonstrate a variable that keeps it's state is a static variable.
                                        One more thing(Trust me it is not personal), There is a big difference between the static variable in the given example by you and my static variable. Your static variable has external-linkage but my static variable has internal linkage inside its scope.
                                        The only and only limitation that I accept for my solution is serialized access(mutex) of the function that holds the static variable in multi-threading(which in this case is not a biggie, is it? ).

                                        1 Reply Last reply
                                        0

                                        • Login

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