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. Widget signal chaining

Widget signal chaining

Scheduled Pinned Locked Moved Solved General and Desktop
qwidgetsignalsnotify
11 Posts 4 Posters 1.3k 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.
  • Pl45m4P Offline
    Pl45m4P Offline
    Pl45m4
    wrote on last edited by Pl45m4
    #1

    Hi guys,

    I could really need some design advices :)

    Assume A is a QWidget-based class, which has a function to do something in constant time.
    I want it to be possible to "chain" these widgets, so that one widget will notify one or more possible successors, where this function is also called then and they will propagate this further on.
    At first, I thought, that would be no problem at all, since I can simply connect them via signals and that's it, but then some doubts came up.

    My idea is that something like this is possible,
    (A_4 and A_5 start after A_3 is done)

    A a1, a2, a3, a4, a5;
    
    a1.next(a2);    //                        A_1
                    //                         |
    a2.next(a3);    //                        A_2 
                    //                         |
    a3.next(a4);    //                        A_3
                    //                        / \
    a3.next(a5);    //                     A_4   A_5
    

    as well as something like this (and any other combination or chain)
    (After A_1, A_2, .... A_n are done, A_3 will start)

    A a1, a2, a3, a4, a5;
    
    a1.next(a3);    //                        A_1     A_2
                    //                           \   /
    a2.next(a3);    //                            A_3
                    //                           /   \                          
    a3.next(a4);    //                        A_4     A_5
    a3.next(a5);
    

    Every widget should be able to be removed at any time without breaking the whole thing and leaking memory.
    Of course I want to avoid dangling pointers and invalid connections, when the receiver got removed/unchained (or a whole widget in this chain got deleted).

    Would it be better for every node in this chain to know its predecessor(s), instead of their next?! Or should I build something like a double-linked list, where previous and next nodes are known by every widget?! How to handle something like this?

    What's the best and cleanest way to do something like this?

    Maybe I am missing the obvious, but it feels like using signals only isn't the best approach in this case.

    Found this topic, it's similar but not quite what I think I can use.

    Any help and ideas for improvement are appreciated :)

    Thanks in advance :)


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

    ~E. W. Dijkstra

    M Pl45m4P 2 Replies Last reply
    0
    • Pl45m4P Pl45m4

      Hi guys,

      I could really need some design advices :)

      Assume A is a QWidget-based class, which has a function to do something in constant time.
      I want it to be possible to "chain" these widgets, so that one widget will notify one or more possible successors, where this function is also called then and they will propagate this further on.
      At first, I thought, that would be no problem at all, since I can simply connect them via signals and that's it, but then some doubts came up.

      My idea is that something like this is possible,
      (A_4 and A_5 start after A_3 is done)

      A a1, a2, a3, a4, a5;
      
      a1.next(a2);    //                        A_1
                      //                         |
      a2.next(a3);    //                        A_2 
                      //                         |
      a3.next(a4);    //                        A_3
                      //                        / \
      a3.next(a5);    //                     A_4   A_5
      

      as well as something like this (and any other combination or chain)
      (After A_1, A_2, .... A_n are done, A_3 will start)

      A a1, a2, a3, a4, a5;
      
      a1.next(a3);    //                        A_1     A_2
                      //                           \   /
      a2.next(a3);    //                            A_3
                      //                           /   \                          
      a3.next(a4);    //                        A_4     A_5
      a3.next(a5);
      

      Every widget should be able to be removed at any time without breaking the whole thing and leaking memory.
      Of course I want to avoid dangling pointers and invalid connections, when the receiver got removed/unchained (or a whole widget in this chain got deleted).

      Would it be better for every node in this chain to know its predecessor(s), instead of their next?! Or should I build something like a double-linked list, where previous and next nodes are known by every widget?! How to handle something like this?

      What's the best and cleanest way to do something like this?

      Maybe I am missing the obvious, but it feels like using signals only isn't the best approach in this case.

      Found this topic, it's similar but not quite what I think I can use.

      Any help and ideas for improvement are appreciated :)

      Thanks in advance :)

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

      @Pl45m4
      Hi,
      If I understand you well, from your description,
      each widged needs to maintain a list of all their parents and another list of all their children.

      You can create a abstract base class with a pure virtual method like:
      void done(parent)=0;

      When all parents have done for a widget, starts himself and when finished, calls done() for all the children.

      Pl45m4P 1 Reply Last reply
      0
      • M mpergand

        @Pl45m4
        Hi,
        If I understand you well, from your description,
        each widged needs to maintain a list of all their parents and another list of all their children.

        You can create a abstract base class with a pure virtual method like:
        void done(parent)=0;

        When all parents have done for a widget, starts himself and when finished, calls done() for all the children.

        Pl45m4P Offline
        Pl45m4P Offline
        Pl45m4
        wrote on last edited by Pl45m4
        #3

        @mpergand said in Widget signal chaining:

        each widged needs to maintain a list of all their parents and another list of all their children.

        From my side there is no need to do that, but this might be one solution.
        Was looking for the "cleanest" way, if there is any.
        I'm not sure about putting a list of pointers to all other widgets in every widget. Deleting a widget will become more difficult then.

        All I'm planing to do is to notify (via signal or something else) the next widget in the chain to start its task.
        Currently I'm not even sure if it's better to work with widget x and let it notify widget x+1 or the other way round ("previous" vs. "next" approach, or both)


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

        ~E. W. Dijkstra

        M 1 Reply Last reply
        0
        • Pl45m4P Pl45m4

          @mpergand said in Widget signal chaining:

          each widged needs to maintain a list of all their parents and another list of all their children.

          From my side there is no need to do that, but this might be one solution.
          Was looking for the "cleanest" way, if there is any.
          I'm not sure about putting a list of pointers to all other widgets in every widget. Deleting a widget will become more difficult then.

          All I'm planing to do is to notify (via signal or something else) the next widget in the chain to start its task.
          Currently I'm not even sure if it's better to work with widget x and let it notify widget x+1 or the other way round ("previous" vs. "next" approach, or both)

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

          @Pl45m4 said in Widget signal chaining:

          I'm not sure about putting a list of pointers to all other widgets in every widget. Deleting a widget will become more difficult then.

          You can use QObject::destroyed signal.
          Or inform any children when a parent is deleted yourself.
          Since you use subclasses of widgets, signals/slots are superflous.
          You can create any methods you want to manage the states of your widgets.

          jeremy_kJ 1 Reply Last reply
          0
          • M mpergand

            @Pl45m4 said in Widget signal chaining:

            I'm not sure about putting a list of pointers to all other widgets in every widget. Deleting a widget will become more difficult then.

            You can use QObject::destroyed signal.
            Or inform any children when a parent is deleted yourself.
            Since you use subclasses of widgets, signals/slots are superflous.
            You can create any methods you want to manage the states of your widgets.

            jeremy_kJ Offline
            jeremy_kJ Offline
            jeremy_k
            wrote on last edited by
            #5

            @mpergand said in Widget signal chaining:

            Since you use subclasses of widgets, signals/slots are superflous.

            Can you clarify this statement?

            Asking a question about code? http://eel.is/iso-c++/testcase/

            M 1 Reply Last reply
            0
            • jeremy_kJ jeremy_k

              @mpergand said in Widget signal chaining:

              Since you use subclasses of widgets, signals/slots are superflous.

              Can you clarify this statement?

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

              @jeremy_k
              Signals and Slots are made to interact to the outside, for ex a button with the mainWindow.
              If you look at QWidget, it doesn't use signals when an internal state has changed, ex: focus, close, show etc, it use events.
              Here, there is no benefice to us signals, it's heavy and complicated.

              jeremy_kJ 1 Reply Last reply
              1
              • M mpergand

                @jeremy_k
                Signals and Slots are made to interact to the outside, for ex a button with the mainWindow.
                If you look at QWidget, it doesn't use signals when an internal state has changed, ex: focus, close, show etc, it use events.
                Here, there is no benefice to us signals, it's heavy and complicated.

                jeremy_kJ Offline
                jeremy_kJ Offline
                jeremy_k
                wrote on last edited by jeremy_k
                #7

                @mpergand said in Widget signal chaining:

                @jeremy_k
                Signals and Slots are made to interact to the outside, for ex a button with the mainWindow.
                If you look at QWidget, it doesn't use signals when an internal state has changed, ex: focus, close, show etc, it use events.
                Here, there is no benefice to us signals, it's heavy and complicated.

                devhost:qtbase/$ git grep connect src/widgets/
                [...]

                A quick glance will show that there are lots of signal and slot uses within complex widgets.

                Asking a question about code? http://eel.is/iso-c++/testcase/

                M 1 Reply Last reply
                0
                • jeremy_kJ jeremy_k

                  @mpergand said in Widget signal chaining:

                  @jeremy_k
                  Signals and Slots are made to interact to the outside, for ex a button with the mainWindow.
                  If you look at QWidget, it doesn't use signals when an internal state has changed, ex: focus, close, show etc, it use events.
                  Here, there is no benefice to us signals, it's heavy and complicated.

                  devhost:qtbase/$ git grep connect src/widgets/
                  [...]

                  A quick glance will show that there are lots of signal and slot uses within complex widgets.

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

                  @jeremy_k
                  If you're talking about compound widgets, yes of course they use signals.

                  1 Reply Last reply
                  1
                  • Pl45m4P Pl45m4

                    Hi guys,

                    I could really need some design advices :)

                    Assume A is a QWidget-based class, which has a function to do something in constant time.
                    I want it to be possible to "chain" these widgets, so that one widget will notify one or more possible successors, where this function is also called then and they will propagate this further on.
                    At first, I thought, that would be no problem at all, since I can simply connect them via signals and that's it, but then some doubts came up.

                    My idea is that something like this is possible,
                    (A_4 and A_5 start after A_3 is done)

                    A a1, a2, a3, a4, a5;
                    
                    a1.next(a2);    //                        A_1
                                    //                         |
                    a2.next(a3);    //                        A_2 
                                    //                         |
                    a3.next(a4);    //                        A_3
                                    //                        / \
                    a3.next(a5);    //                     A_4   A_5
                    

                    as well as something like this (and any other combination or chain)
                    (After A_1, A_2, .... A_n are done, A_3 will start)

                    A a1, a2, a3, a4, a5;
                    
                    a1.next(a3);    //                        A_1     A_2
                                    //                           \   /
                    a2.next(a3);    //                            A_3
                                    //                           /   \                          
                    a3.next(a4);    //                        A_4     A_5
                    a3.next(a5);
                    

                    Every widget should be able to be removed at any time without breaking the whole thing and leaking memory.
                    Of course I want to avoid dangling pointers and invalid connections, when the receiver got removed/unchained (or a whole widget in this chain got deleted).

                    Would it be better for every node in this chain to know its predecessor(s), instead of their next?! Or should I build something like a double-linked list, where previous and next nodes are known by every widget?! How to handle something like this?

                    What's the best and cleanest way to do something like this?

                    Maybe I am missing the obvious, but it feels like using signals only isn't the best approach in this case.

                    Found this topic, it's similar but not quite what I think I can use.

                    Any help and ideas for improvement are appreciated :)

                    Thanks in advance :)

                    Pl45m4P Offline
                    Pl45m4P Offline
                    Pl45m4
                    wrote on last edited by Pl45m4
                    #9

                    First of all, thanks to all of you for your comments and suggestions :)

                    Coming back to this, I decided to make something like QButtonGroup containing my widgets, to manage the chaining and notifications. I want to keep this private, so that it will be not a part of my widget's "API". Therefore I created a class similar to QButtonGroup's code and added signals and functions.

                    Since I have some experience in Qt in general but almost none in developing Qt plugins (QtDesigner plugins / widget "libraries") I'm wondering if it can/should be done like this?
                    Would it be better to subclass QButtonGroup (my widgets are QAbstractButton subclasses)?


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

                    ~E. W. Dijkstra

                    Pl45m4P 1 Reply Last reply
                    0
                    • Pl45m4P Pl45m4

                      First of all, thanks to all of you for your comments and suggestions :)

                      Coming back to this, I decided to make something like QButtonGroup containing my widgets, to manage the chaining and notifications. I want to keep this private, so that it will be not a part of my widget's "API". Therefore I created a class similar to QButtonGroup's code and added signals and functions.

                      Since I have some experience in Qt in general but almost none in developing Qt plugins (QtDesigner plugins / widget "libraries") I'm wondering if it can/should be done like this?
                      Would it be better to subclass QButtonGroup (my widgets are QAbstractButton subclasses)?

                      Pl45m4P Offline
                      Pl45m4P Offline
                      Pl45m4
                      wrote on last edited by Pl45m4
                      #10

                      Solved.
                      Made some kind of manager class to organize the widget chain / hierarchy. So not the widgets know about the next or prev actions, but only the managing class knows. The widgets just have to know when it's their turn (notification comes via call or signal from controlling obj).
                      The tree / structure is also built in the controlling obj


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

                      ~E. W. Dijkstra

                      Christian EhrlicherC 1 Reply Last reply
                      0
                      • Pl45m4P Pl45m4 has marked this topic as solved on
                      • Pl45m4P Pl45m4

                        Solved.
                        Made some kind of manager class to organize the widget chain / hierarchy. So not the widgets know about the next or prev actions, but only the managing class knows. The widgets just have to know when it's their turn (notification comes via call or signal from controlling obj).
                        The tree / structure is also built in the controlling obj

                        Christian EhrlicherC Offline
                        Christian EhrlicherC Offline
                        Christian Ehrlicher
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        Not read the whole thread but maybe this is of interest: https://wiki.qt.io/TaskTree

                        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                        Visit the Qt Academy at https://academy.qt.io/catalog

                        1 Reply Last reply
                        1
                        • Pl45m4P Pl45m4 referenced this topic on

                        • Login

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