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. Connecting Signals in dynamically created objects to Slots in MainWindow
QtWS25 Last Chance

Connecting Signals in dynamically created objects to Slots in MainWindow

Scheduled Pinned Locked Moved Unsolved General and Desktop
signal & slotmainwindow
10 Posts 4 Posters 2.4k 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.
  • E Offline
    E Offline
    EaccB
    wrote on last edited by
    #1

    I'm trying to keep all my GUI code inside MainWindow, in order to follow best practice.

    I have a class A (instantiated in MainWindow) which holds dynamically created instances of class B inside a QList.

    The instances of class B need to emit a signal when their data changes. A slot in MainWindow needs to receive these signals.

    The obvious solution is to either store a pointer to MainWindow in a global variable, or pass a pointer to Mainwindow to class A, and then the instances of class B, and do the Connect() inside class B. However, I've been told it is bad practice to expose MainWindow to other classes. Also don't like the idea of passing MainWindow to class A just so it can be passed to class B.

    What's the best way to approach this problem?

    JonBJ 1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Let class B emit a signal, connect this signal in the MainWindow.

      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
      3
      • E EaccB

        I'm trying to keep all my GUI code inside MainWindow, in order to follow best practice.

        I have a class A (instantiated in MainWindow) which holds dynamically created instances of class B inside a QList.

        The instances of class B need to emit a signal when their data changes. A slot in MainWindow needs to receive these signals.

        The obvious solution is to either store a pointer to MainWindow in a global variable, or pass a pointer to Mainwindow to class A, and then the instances of class B, and do the Connect() inside class B. However, I've been told it is bad practice to expose MainWindow to other classes. Also don't like the idea of passing MainWindow to class A just so it can be passed to class B.

        What's the best way to approach this problem?

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

        @EaccB said in Connecting Signals in dynamically created objects to Slots in MainWindow:

        The instances of class B need to emit a signal when their data changes. A slot in MainWindow needs to receive these signals.

        and do the Connect() inside class B.

        Why would you want to do the connect() inside class B? B emit()s, it's not its job to connect to any slot: in fact, part of the point of signals/slots is precisely that the emitter doesn't know about any listeners, so it can't do connects. Do the connect()s in the caller creating instances of B, not in B. So in A here. Or back in MainWindow if you can, depending on its interface with class A instances.

        E 1 Reply Last reply
        2
        • JonBJ JonB

          @EaccB said in Connecting Signals in dynamically created objects to Slots in MainWindow:

          The instances of class B need to emit a signal when their data changes. A slot in MainWindow needs to receive these signals.

          and do the Connect() inside class B.

          Why would you want to do the connect() inside class B? B emit()s, it's not its job to connect to any slot: in fact, part of the point of signals/slots is precisely that the emitter doesn't know about any listeners, so it can't do connects. Do the connect()s in the caller creating instances of B, not in B. So in A here. Or back in MainWindow if you can, depending on its interface with class A instances.

          E Offline
          E Offline
          EaccB
          wrote on last edited by
          #4

          @JonB

          How would I connect the signal in class B to MainWindow, in class A?
          Or are you saying I should connect the signal in B to a slot in A, which emits a signal which is received by a slot in MainWindow? If so, isn't this indirect "chaining" rather unwieldy?

          JonBJ 1 Reply Last reply
          0
          • E EaccB

            @JonB

            How would I connect the signal in class B to MainWindow, in class A?
            Or are you saying I should connect the signal in B to a slot in A, which emits a signal which is received by a slot in MainWindow? If so, isn't this indirect "chaining" rather unwieldy?

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

            @EaccB
            I assume MainWindow creates a class A instance, I don't know whether one or many. Class A creates the Bs. Can the MainWindow hook the slots after it has created the A? One thing for sure is that class B should not be doing the connects.

            E 1 Reply Last reply
            0
            • JonBJ JonB

              @EaccB
              I assume MainWindow creates a class A instance, I don't know whether one or many. Class A creates the Bs. Can the MainWindow hook the slots after it has created the A? One thing for sure is that class B should not be doing the connects.

              E Offline
              E Offline
              EaccB
              wrote on last edited by
              #6

              @JonB

              MainWindow creates 1 instance of class A. Class A creates multiple instances of class B.

              JonBJ 1 Reply Last reply
              0
              • E EaccB

                @JonB

                MainWindow creates 1 instance of class A. Class A creates multiple instances of class B.

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

                @EaccB

                MainWindow:
                    a = new A()
                    foreach (b in a.listOfBs)
                        connect(b, signal, this, slot)
                

                ?

                E 1 Reply Last reply
                1
                • JonBJ JonB

                  @EaccB

                  MainWindow:
                      a = new A()
                      foreach (b in a.listOfBs)
                          connect(b, signal, this, slot)
                  

                  ?

                  E Offline
                  E Offline
                  EaccB
                  wrote on last edited by EaccB
                  #8

                  @JonB

                  Right, so basically returning the instances of B back to MainWindow?

                  As B is instantiated dynamically, should I emit a Signal from A to MainWindow, when a new instance of B is created, so the connection can be made?

                  JonBJ 1 Reply Last reply
                  0
                  • E EaccB

                    @JonB

                    Right, so basically returning the instances of B back to MainWindow?

                    As B is instantiated dynamically, should I emit a Signal from A to MainWindow, when a new instance of B is created, so the connection can be made?

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

                    @EaccB
                    So you're saying that as your program runs new instances of B will be created periodically, and the main window has a slot which needs to be connected to a signal from B, right?

                    Doubtless use cases vary, but, yes, why not have a helper method for creating a new B which emits a signal. Mainwindow has a slot for that, and connects the freshly created B to its slot. The good thing is that when the hierarchy becomes deeper and you have A creating B creating C creating D, you can still use this principle to connect D's signal to the main window without passing the main window down all over the place.

                    Unless a Qt expert says otherwise...

                    1 Reply Last reply
                    1
                    • mrjjM Offline
                      mrjjM Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      Hi
                      Just as a note.
                      It's also possible to do signal to signal connects.
                      So if MainWindow just needs to know data has changed to reload something
                      then you could also

                      Define new Signal in class A
                      void DataChangedForB

                      and internally when you create the B's, connect B's
                      signal datachanged to A::DataChangedForB signal

                      And then in MainWindow, simply connect Mains slot to
                      the new A::DataChangedForB signal

                      However, if you are using sender() to access the B' instance, this wont work.

                      1 Reply Last reply
                      2

                      • Login

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