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. When to use signals and slots, versus direct function calls, from parent to child?
Forum Updated to NodeBB v4.3 + New Features

When to use signals and slots, versus direct function calls, from parent to child?

Scheduled Pinned Locked Moved Solved General and Desktop
16 Posts 8 Posters 796 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.
  • J JohnB
    28 Mar 2025, 04:16

    I thought I understood signals and slots pretty well, but the more I get into it, the less I know (or so it seems).

    Using Qt and C++, subclassing QWidget (or QDialog, QLabel, or QMostAnythingElse), what are the considerations of having the parent widget directly call a function in the subclassed QWidget, as opposed to having the parent widget emit a signal which is handled by a slot in the subclassed QDialog? While studying this topic I looked at several of the Qt widgets (QWidget, QLabel, QAbstractButton and others) to see how Qt itself does this. I see that these classes have a mix of both signal / slot mechanisms as well as direct public functions. Is there any rhyme or reason as to which mechanism to use?

    Specifically, for a card game, I'm creating a subclass of QWidget (for simplicity I'll call it a dialog) to get the number of players (2-5) and optionally their names. For initializing, the parent window calls a function in the dialog, GetPlayerInfo (QList<QString> players) so the parent window can tell the dialog what (if any) players are already known, and allow user interaction to change the number of players and names. After the user sets up everything and clicks Next, this child window emits a signal, SetPlayers (QList <QString> to send the updated QList<Player> back to the parent. The parent then squirrels away this information, and moves on the the next stage of the game, shuffle and deal. So back to the 1st paragraph, what are the considerations for using signal / slot or direct function calls?

    Thanks for any help. Since this is my first query here since almost forever, please excuse any goofs and tell me what to correct for next time.

    J Offline
    J Offline
    JonB
    wrote on 28 Mar 2025, 08:27 last edited by
    #4

    @JohnB
    One important distinction: signals/slots, unlike direct calls, are one way, from signaller to slotter. There is no way to get any information back from the recipient --- no return value, not even a "success/failure". That may make a huge difference in certain cases.

    J G 2 Replies Last reply 28 Mar 2025, 12:06
    1
    • J JonB
      28 Mar 2025, 08:27

      @JohnB
      One important distinction: signals/slots, unlike direct calls, are one way, from signaller to slotter. There is no way to get any information back from the recipient --- no return value, not even a "success/failure". That may make a huge difference in certain cases.

      J Offline
      J Offline
      JoeCFD
      wrote on 28 Mar 2025, 12:06 last edited by JoeCFD
      #5

      @JonB said in When to use signals and slots, versus direct function calls, from parent to child?:

      the recipient

      The recipient knows the sender and can use it to call back or send a signal back.
      I guess direct calls can easily freeze or crash the GUI app as Axel explained.

      One design issue here is how to connect widgets if gui layout has a few layers. Would like to know how you guys did it.

      J 1 Reply Last reply 28 Mar 2025, 15:05
      0
      • J Offline
        J Offline
        JohnB
        wrote on 28 Mar 2025, 14:20 last edited by
        #6

        Thanks, all, for your answers so far. I'm looking at a very specific case from Qt's QAbstractButton, and trying to decide how I would implement some of its operations if I were designing it -- i.e., best practices. SetIcon() is a direct function call, whereas the very similar-sounding SetIconSize() is a slot. SetCheckable() is a function call, but SetChecked() is a slot. These use cases all seem very similar conceptually, yet some are function calls and some are slots. It's not obvious what the differences are. Even considering the suggestions given so far, I'm not sure how they would lead an outsider to make the same choices. Maybe it does not really matter much in many situations, and I'm just overthinking it.

        J 1 Reply Last reply 28 Mar 2025, 14:56
        0
        • J JohnB
          28 Mar 2025, 14:20

          Thanks, all, for your answers so far. I'm looking at a very specific case from Qt's QAbstractButton, and trying to decide how I would implement some of its operations if I were designing it -- i.e., best practices. SetIcon() is a direct function call, whereas the very similar-sounding SetIconSize() is a slot. SetCheckable() is a function call, but SetChecked() is a slot. These use cases all seem very similar conceptually, yet some are function calls and some are slots. It's not obvious what the differences are. Even considering the suggestions given so far, I'm not sure how they would lead an outsider to make the same choices. Maybe it does not really matter much in many situations, and I'm just overthinking it.

          J Offline
          J Offline
          JonB
          wrote on 28 Mar 2025, 14:56 last edited by
          #7

          @JohnB
          There is nothing special about a slot, only a signal. A slot is just a function, you can call it directly any time you like, nothing to do with signals. The fact that Qt has chosen to classify some methods as slots essentially only means that it would not be surprising if you used them as the slots for signals. A slot ought not to return a value insofar as that cannot be used if it is called from a signal, though it could do if called directly, but since it is intended to be useful from a signal it really ought be void and not take "out" parameters.

          Don't worry too much about slots, only about signals.

          1 Reply Last reply
          1
          • J JoeCFD
            28 Mar 2025, 12:06

            @JonB said in When to use signals and slots, versus direct function calls, from parent to child?:

            the recipient

            The recipient knows the sender and can use it to call back or send a signal back.
            I guess direct calls can easily freeze or crash the GUI app as Axel explained.

            One design issue here is how to connect widgets if gui layout has a few layers. Would like to know how you guys did it.

            J Offline
            J Offline
            JonB
            wrote on 28 Mar 2025, 15:05 last edited by JonB
            #8

            @JoeCFD said in When to use signals and slots, versus direct function calls, from parent to child?:

            The recipient knows the sender and can use it to call back or send a signal back.

            But that is not at all the same thing as a direct function call, e.g. with a return result and/or "out" parameters. Nor is it the same if connect()s are anything other than DirectConnection.

            I don't know what you mean about "The recipient knows the sender". Do you mean via QObject *QObject::sender() const? Which is not a great idea to use, has cases where it is not valid/available as per the docs and, I believe, other cases where it is not valid either. As I'm sure you know :)

            J 1 Reply Last reply 28 Mar 2025, 15:25
            0
            • J JonB
              28 Mar 2025, 15:05

              @JoeCFD said in When to use signals and slots, versus direct function calls, from parent to child?:

              The recipient knows the sender and can use it to call back or send a signal back.

              But that is not at all the same thing as a direct function call, e.g. with a return result and/or "out" parameters. Nor is it the same if connect()s are anything other than DirectConnection.

              I don't know what you mean about "The recipient knows the sender". Do you mean via QObject *QObject::sender() const? Which is not a great idea to use, has cases where it is not valid/available as per the docs and, I believe, other cases where it is not valid either. As I'm sure you know :)

              J Offline
              J Offline
              JoeCFD
              wrote on 28 Mar 2025, 15:25 last edited by JoeCFD
              #9

              @JonB It is true that using sender() has issues. But I do use it when needed in my app.

              J 1 Reply Last reply 28 Mar 2025, 15:27
              0
              • J JoeCFD
                28 Mar 2025, 15:25

                @JonB It is true that using sender() has issues. But I do use it when needed in my app.

                J Offline
                J Offline
                JonB
                wrote on 28 Mar 2025, 15:27 last edited by JonB
                #10

                @JoeCFD
                :) Let's put it this way: for the OP trying to get to grips with Qt, signals and slots, I think you would agree we should not be encouraging them to use sender() or know anything about the sender at this stage.

                As an aside, using a lambda with a parameter or even a QSignalMapper seems a cleaner way of passing information about the sender to the receiver, if it is really needed. But I still think this is "advanced" for the initial level the OP is at.

                J 1 Reply Last reply 28 Mar 2025, 15:52
                1
                • J JonB
                  28 Mar 2025, 15:27

                  @JoeCFD
                  :) Let's put it this way: for the OP trying to get to grips with Qt, signals and slots, I think you would agree we should not be encouraging them to use sender() or know anything about the sender at this stage.

                  As an aside, using a lambda with a parameter or even a QSignalMapper seems a cleaner way of passing information about the sender to the receiver, if it is really needed. But I still think this is "advanced" for the initial level the OP is at.

                  J Offline
                  J Offline
                  JoeCFD
                  wrote on 28 Mar 2025, 15:52 last edited by JoeCFD
                  #11

                  @JonB said in When to use signals and slots, versus direct function calls, from parent to child?:

                  :) Let's put it this way: for the OP trying to get to grips with Qt, signals and slots, I think you would agree we should not be encouraging them to use sender() or know anything about the sender at this stage.

                  Why not? If two widgets are connected, they (can) know each other well. The issues with using sender() are similar like in the callback mechanism(store the sender pointer insider recipient).

                  1 Reply Last reply
                  0
                  • J JonB
                    28 Mar 2025, 08:27

                    @JohnB
                    One important distinction: signals/slots, unlike direct calls, are one way, from signaller to slotter. There is no way to get any information back from the recipient --- no return value, not even a "success/failure". That may make a huge difference in certain cases.

                    G Offline
                    G Offline
                    GrecKo
                    Qt Champions 2018
                    wrote on 28 Mar 2025, 15:56 last edited by
                    #12

                    @JonB said in When to use signals and slots, versus direct function calls, from parent to child?:

                    One important distinction: signals/slots, unlike direct calls, are one way, from signaller to slotter. There is no way to get any information back from the recipient --- no return value, not even a "success/failure". That may make a huge difference in certain cases.

                    Just to be pedantic: that's not actually the case. If a signal has the same return type as the slot it is connected to, the return value of the slot will be correctly forwarded back to the signal (unless the connection is queued ofc.)

                    But please do use a lambda instead.

                    J P 2 Replies Last reply 28 Mar 2025, 16:03
                    1
                    • G GrecKo
                      28 Mar 2025, 15:56

                      @JonB said in When to use signals and slots, versus direct function calls, from parent to child?:

                      One important distinction: signals/slots, unlike direct calls, are one way, from signaller to slotter. There is no way to get any information back from the recipient --- no return value, not even a "success/failure". That may make a huge difference in certain cases.

                      Just to be pedantic: that's not actually the case. If a signal has the same return type as the slot it is connected to, the return value of the slot will be correctly forwarded back to the signal (unless the connection is queued ofc.)

                      But please do use a lambda instead.

                      J Offline
                      J Offline
                      JonB
                      wrote on 28 Mar 2025, 16:03 last edited by
                      #13

                      @GrecKo said in When to use signals and slots, versus direct function calls, from parent to child?:

                      If a signal has the same return type as the slot it is connected to, the return value of the slot will be correctly forwarded back to the signal (unless the connection is queued ofc.)

                      I did not know that! I have always declared my signals void, and thought they had to be. Is it documented anywhere?

                      And as we are both saying, signals/slots can be queued, and that is quite different behaviour from when the OP is comparing against direct function calls.

                      1 Reply Last reply
                      1
                      • Z Offline
                        Z Offline
                        zvoopz
                        wrote on 28 Mar 2025, 16:54 last edited by
                        #14

                        As far as I know Qt was a pioneer who has introduced signal-slot mechanism in middle of 1990th. It is the most beautiful approach to provide safe and robust class communication that has inspired many followers. I like to use it

                        1 Reply Last reply
                        0
                        • G GrecKo
                          28 Mar 2025, 15:56

                          @JonB said in When to use signals and slots, versus direct function calls, from parent to child?:

                          One important distinction: signals/slots, unlike direct calls, are one way, from signaller to slotter. There is no way to get any information back from the recipient --- no return value, not even a "success/failure". That may make a huge difference in certain cases.

                          Just to be pedantic: that's not actually the case. If a signal has the same return type as the slot it is connected to, the return value of the slot will be correctly forwarded back to the signal (unless the connection is queued ofc.)

                          But please do use a lambda instead.

                          P Offline
                          P Offline
                          Pl45m4
                          wrote on 29 Mar 2025, 02:03 last edited by
                          #15

                          @GrecKo said in When to use signals and slots, versus direct function calls, from parent to child?:

                          Just to be pedantic: that's not actually the case. If a signal has the same return type as the slot it is connected to, the return value of the slot will be correctly forwarded back to the signal (unless the connection is queued ofc.)

                          I've never seen this before in working code. Proof please ;-)
                          I'm with @JonB, when I learned about signals it was told (somewhere, I think even in the Qt Documentation) that signals are always declared with void.
                          (technically void functions that are being caught by MOC when parsing the code to make the connection and "call" the slot/connected function when the signal "function" is called/emitted)

                          @SuhasKrishanamurthy
                          why does your answer look like it was written by ChatGPT?! ;-)
                          I'm pretty sure OP could have done that himself if he wanted to ;-)


                          If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                          ~E. W. Dijkstra

                          J 1 Reply Last reply 29 Mar 2025, 07:59
                          0
                          • P Pl45m4
                            29 Mar 2025, 02:03

                            @GrecKo said in When to use signals and slots, versus direct function calls, from parent to child?:

                            Just to be pedantic: that's not actually the case. If a signal has the same return type as the slot it is connected to, the return value of the slot will be correctly forwarded back to the signal (unless the connection is queued ofc.)

                            I've never seen this before in working code. Proof please ;-)
                            I'm with @JonB, when I learned about signals it was told (somewhere, I think even in the Qt Documentation) that signals are always declared with void.
                            (technically void functions that are being caught by MOC when parsing the code to make the connection and "call" the slot/connected function when the signal "function" is called/emitted)

                            @SuhasKrishanamurthy
                            why does your answer look like it was written by ChatGPT?! ;-)
                            I'm pretty sure OP could have done that himself if he wanted to ;-)

                            J Offline
                            J Offline
                            JonB
                            wrote on 29 Mar 2025, 07:59 last edited by
                            #16

                            @Pl45m4 said in When to use signals and slots, versus direct function calls, from parent to child?:

                            I've never seen this before in working code. Proof please ;-)

                            #ifndef SIGNALTEST_H
                            #define SIGNALTEST_H
                            
                            #include <QObject>
                            
                            class SignalTest : public QObject
                            {
                                Q_OBJECT
                            public:
                                explicit SignalTest(QObject *parent = nullptr);
                            
                            public slots:
                                int intSlot() { return 123456; }
                            
                            signals:
                                int intSignal();
                            };
                            
                            #endif // SIGNALTEST_H
                            
                                SignalTest *obj = new SignalTest;
                                QObject::connect(obj, &SignalTest::intSignal, obj, &SignalTest::intSlot, Qt::DirectConnection);
                                qDebug() << /*emit*/ obj->intSignal();
                            

                            We do indeed get 123456 printed as return value from signal call, as per @GrecKo.

                            I do not think any of the (documented, at least) signals used by Qt have a return value, but it does work. Of course, if I change to Qt::QueuedConnection it does not work, I get 0 back.

                            Googling, even @SGaist wrote in https://forum.qt.io/post/596362

                            Signals have no return value.

                            And in the "other" forum someone wrote in https://www.qtcentre.org/threads/70910-How-to-get-the-return-value-when-signal-emit?p=307681#post307681

                            All signals and slots have a "void" return value. You cannot return anything that way.

                            But over at stackoverflow the accepted answer at https://stackoverflow.com/a/5903082/489865 shows same as mine but with a QString return and discusses it a bit further.

                            So it seems this is a little known "feature". I do not see the Qt docs saying anything about this, neither that signals should be void nor what happens if they return a value.

                            1 Reply Last reply
                            1
                            • J JohnB has marked this topic as solved on 29 Mar 2025, 13:19

                            13/16

                            28 Mar 2025, 16:03

                            • Login

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