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. Callback-Slot mechanism

Callback-Slot mechanism

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 6 Posters 1.1k 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.
  • K Offline
    K Offline
    kain
    wrote on last edited by
    #1

    Hey there,

    I am currently writing an application which controls several motors/sensors and with a small UI/HMI for that. I have some kind of an fundamental question about how to achieve a nice callback-mechanism.
    Right now I have a set of controller-classes which handle my low-level business-logic. These controllers are called by several QObjects using signal/slot mechanisms. To model my process I am currently evaluating QStateMachine-framework using Slots for &QState::entered-signals which then call my low-level controller-classes.
    To report the sucess/failure of any action I want my controller-classes to emit a signal which should be connected to a slot of that calling code. For example I would have my QStateMachine wait in a state until the controller-class emits some 'sucess' signal.
    One solution I might think of is, that my controller-classes each have only one slot left which accept some QObject as parameter. That QObject itself would have some information on what method was requested (QString?! ) and a signal that has to be emittet on completition/failure.
    Is there any best-practice for that?

    1 Reply Last reply
    0
    • fcarneyF Offline
      fcarneyF Offline
      fcarney
      wrote on last edited by
      #2

      Are you asking about a best practice for encapsulating a message in a system?

      The only best practice I can think of is modeling your system in a state diagram to make sure you capture the different states your system can be in. As far as best practice for a messaging system there are probably dozens of ways people do that. Sometimes a string works, sometimes you need more data and encapsulating that data in a specialized object works. It all depends upon your requirements needed after you model your system. So having a better understanding of your inputs and outputs might decide where to go next.

      Is this answer vague enough? ;-)

      C++ is a perfectly valid school of magic.

      1 Reply Last reply
      3
      • dheerendraD Offline
        dheerendraD Offline
        dheerendra
        Qt Champions 2022
        wrote on last edited by
        #3
        1. Controllers are interacting with sensors ? Are the qobjects ? One sensor maps to one cotroller ?
        2. How the are related to UI ?
        3. From where do u want call back ?
        4. UI to sensors and Sensors to UI communication exists ?
          May be some clear details will help.

        Dheerendra
        @Community Service
        Certified Qt Specialist
        http://www.pthinks.com

        K 1 Reply Last reply
        0
        • K Offline
          K Offline
          kain
          wrote on last edited by
          #4

          Hm, not quite what I was thinking of I guess.
          I don't want to call every slot in a synchronous way (i.e. BlockingQueuedConnection) just to be able to get the information that is returned/generated by this slot. For simplicity this might be just 'true' or 'false' or 'Success' or 'Failure'.
          So I have my controllerObject ControllerA with some slot

          void ControllerA::doSomeThing()
          

          ProcessA is another QObject which invokes this slot. To be able to get some information back, I would create a signal on ControllerA and a corresponding Slot on ProcessA. ControllerA uses a StateMachine to save its current state and triggers a transition (using a private signal) when its own Slot is invoked. This might work in a very basic approach, but things will get inconsistent when another QObject ProessB also invokes ControllerA::doSomething() because ControllerA would again emit a Signal which will then invoke the Slot on ProcessA (and ProcessB). Or I use QMutex, but this is as good as running synchronous.

          To circumvent this problem I want that callback-mechanism, i.e. to be able to control which Slot gets invoked.

          Another example might be a simple Dialog with 2 Options (Yes, No) in the UI. The dialog would be invoked via Slot which is connected to many Signals in the backend. How would I get the result of that dialog (Y/N) back to the calling object only?

          jsulmJ 1 Reply Last reply
          0
          • dheerendraD dheerendra
            1. Controllers are interacting with sensors ? Are the qobjects ? One sensor maps to one cotroller ?
            2. How the are related to UI ?
            3. From where do u want call back ?
            4. UI to sensors and Sensors to UI communication exists ?
              May be some clear details will help.
            K Offline
            K Offline
            kain
            wrote on last edited by
            #5

            @dheerendra

            1. Yes, Controllers are interacting with IO, sensors and actors mixed and yes, they are QObjects
            2. If some errors occur, I think it is nice to report the UI. Of cource the controller could just report the error to the QObject managing the process, but there is the same problem here
            3. I want to callback from a invoked slot.. Maybe from some controller-Slot ControllerC::StartMotorRPM(int rpm). The callback should then report some sucess or error-code
            4. Ui to sensors existis, how to implement they way Sensor to UI is part of my question
            J.HilkJ 1 Reply Last reply
            0
            • K kain

              Hm, not quite what I was thinking of I guess.
              I don't want to call every slot in a synchronous way (i.e. BlockingQueuedConnection) just to be able to get the information that is returned/generated by this slot. For simplicity this might be just 'true' or 'false' or 'Success' or 'Failure'.
              So I have my controllerObject ControllerA with some slot

              void ControllerA::doSomeThing()
              

              ProcessA is another QObject which invokes this slot. To be able to get some information back, I would create a signal on ControllerA and a corresponding Slot on ProcessA. ControllerA uses a StateMachine to save its current state and triggers a transition (using a private signal) when its own Slot is invoked. This might work in a very basic approach, but things will get inconsistent when another QObject ProessB also invokes ControllerA::doSomething() because ControllerA would again emit a Signal which will then invoke the Slot on ProcessA (and ProcessB). Or I use QMutex, but this is as good as running synchronous.

              To circumvent this problem I want that callback-mechanism, i.e. to be able to control which Slot gets invoked.

              Another example might be a simple Dialog with 2 Options (Yes, No) in the UI. The dialog would be invoked via Slot which is connected to many Signals in the backend. How would I get the result of that dialog (Y/N) back to the calling object only?

              jsulmJ Online
              jsulmJ Online
              jsulm
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @kain said in Callback-Slot mechanism:

              but things will get inconsistent when another QObject ProessB also invokes ControllerA::doSomething() because ControllerA would again emit a Signal which will then invoke the Slot on Process

              Slots are not executed at the same time. The event loop takes one signal from the queue and executes connected slots one after the other.

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

              1 Reply Last reply
              1
              • K kain

                @dheerendra

                1. Yes, Controllers are interacting with IO, sensors and actors mixed and yes, they are QObjects
                2. If some errors occur, I think it is nice to report the UI. Of cource the controller could just report the error to the QObject managing the process, but there is the same problem here
                3. I want to callback from a invoked slot.. Maybe from some controller-Slot ControllerC::StartMotorRPM(int rpm). The callback should then report some sucess or error-code
                4. Ui to sensors existis, how to implement they way Sensor to UI is part of my question
                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by
                #7

                @kain
                I think, I get what you try to do, I'm however not entirely sure.

                I had something similar last year. A program that controls a couple of motors, each basically the same , just a different io-port.

                So I ended up creating one base class with a enumeration about the motor type During initialization(construction) you can assign the instance the correct enum value.
                And each signal(from the base class) than also transmit its own typ to the motor-manager class for a clear differentiation.


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                K 1 Reply Last reply
                4
                • J.HilkJ J.Hilk

                  @kain
                  I think, I get what you try to do, I'm however not entirely sure.

                  I had something similar last year. A program that controls a couple of motors, each basically the same , just a different io-port.

                  So I ended up creating one base class with a enumeration about the motor type During initialization(construction) you can assign the instance the correct enum value.
                  And each signal(from the base class) than also transmit its own typ to the motor-manager class for a clear differentiation.

                  K Offline
                  K Offline
                  kain
                  wrote on last edited by kain
                  #8

                  @J.Hilk
                  Yes, this is kind of the application that I am developing. Another example is my ControllerA class beingt used my different other QObjects: UI, some NetworkSocket, another ControllerB, etc. So if my ControllerA emits a signal, I just want the corresponding QObject that made the Request to be 'signalled'. That is, if my ControllerA has some Slot invoked by a NetworkSocket-QObject, I do not want any slot invocation on my UI or my ControllerB about that but only on that NetworkSocket-QObject.
                  One idea I might follow is to create some callback-QObject like

                  class RequestCallback : public QObject
                  {
                      Q_OBJECT
                  public:
                      explicit Request(QObject *parent = nullptr);
                  signal:
                    void someSignal(int returnCode);
                  }
                  

                  With that method I could create one such RequestCallback object everytime I want to invoke somethink and pass that QObject to that invoked slot. The slot could just 'emit someSignal(0)' for example.
                  This looks to me like some kind of workaround because I will probably need a several RequestCallback-objects. Or are there any better ideas?

                  M 1 Reply Last reply
                  0
                  • K kain

                    @J.Hilk
                    Yes, this is kind of the application that I am developing. Another example is my ControllerA class beingt used my different other QObjects: UI, some NetworkSocket, another ControllerB, etc. So if my ControllerA emits a signal, I just want the corresponding QObject that made the Request to be 'signalled'. That is, if my ControllerA has some Slot invoked by a NetworkSocket-QObject, I do not want any slot invocation on my UI or my ControllerB about that but only on that NetworkSocket-QObject.
                    One idea I might follow is to create some callback-QObject like

                    class RequestCallback : public QObject
                    {
                        Q_OBJECT
                    public:
                        explicit Request(QObject *parent = nullptr);
                    signal:
                      void someSignal(int returnCode);
                    }
                    

                    With that method I could create one such RequestCallback object everytime I want to invoke somethink and pass that QObject to that invoked slot. The slot could just 'emit someSignal(0)' for example.
                    This looks to me like some kind of workaround because I will probably need a several RequestCallback-objects. Or are there any better ideas?

                    M Offline
                    M Offline
                    mpergand
                    wrote on last edited by mpergand
                    #9

                    @kain said in Callback-Slot mechanism:

                    This looks to me like some kind of workaround because I will probably need a several RequestCallback-objects. Or are there any better ideas?

                    This makes me think of some sort of Notification Center.
                    Some objects emit a notificarion and other objects register themselves to receive that notification.
                    For example, with the preferences Dialog, when the user click OK, the prefDialog emits a PrefsDidChanged notification. Each windows or views that need to be informed of any changes register itself to receive that notification.
                    I'm using custom events to emit this notification.

                    EventCenter().addObserver(this, Event_AppPrefsDidChange);
                    

                    This line register 'this' to receive the AppPrefsDidChange notif.
                    The notificationCenter post the event:

                    QApplication::postEvent(o.observer,new CustomEvent(eventType,sender));
                    

                    And in the receiver:

                    void TextDocWindow::customEvent(QEvent* event)
                    {
                        CustomEvent* ev =static_cast<CustomEvent*>(event);
                    
                        switch (ev->subType())
                            {
                            case Event_AppPrefsDidChange:
                                Log("Prefs changed");
                                setupFromPrefs();
                                break;
                            }
                    }
                    

                    Here it's a text editor, the prefs changes can be color of text, size of font. etc.
                    In the custom event object, you can pass any information you need to the receiver:

                    class CustomEvent : public QEvent
                    {
                    
                    	public:
                    
                    		CustomEvent(uint type,QObject* sender);
                    	virtual ~CustomEvent()
                    			{
                    			}
                    
                    	QObject*	sender() { return oSender; }
                    	uint	subType() { return vSubType; }
                    
                    	private:
                    
                    	QObject*	oSender;
                    	          uint	vSubType;
                    
                    };
                    

                    It's possible to receive a type of notification from a particular object only.

                    void	addObserver(QObject *observer, uint eventType, QObject* sender=0);
                    

                    Here it is the sender extra parameter.

                    VoilĂ , just an idea, hope it can help you.

                    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