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. Best way to make 2 differents subclasses communicate

Best way to make 2 differents subclasses communicate

Scheduled Pinned Locked Moved General and Desktop
16 Posts 3 Posters 4.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.
  • M Offline
    M Offline
    Max13
    wrote on last edited by
    #1

    Hello !

    I'm subclassing QMainWindow as MainWindow and QWidget as ConnectionWidget which have to be a central widget. I want my centralWidgets being able to change the QStatusBar from MainWindow easily, what is the best way to do it ?

    Here is what I thought about: I've added to MainWindow a slot (MainWindow::showMessage(...), which calls MainWindow->statusBar()->showMessage(...)) which will be called by the central widgets (here: ConnectionWidget). It seems a little ugly, because I HAVE to store the parent in ConnectionWidget which MUST be a MainWindow, and I've been told to use delegates instead.

    So here is my question: Is my approach a good way, are delegates better for this, or should I reimplement "setCentralWidget" to connect the children signals instead of doing it IN the children, or any other?

    Thank you for your help.

    -- EDIT --
    I can't connect my ConnectionWidget directly to MainWindow->statusBar() because when a message timeouts, I show the last permanent message, which is stored in MainWindow.

    We all have started by asking questions. Then after some time, we can begin answering them.

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Why not have your ConnectionWidget emit a signal with a QString parameter and connect it to the QMainWindow statusbar slot showMessage() ?

      MainWindow.cpp
      @
      ConnectionWidget *connectionWidget = new ConnectionWidget;
      connect(connectionWidget, SIGNAL(messageToShow(QString)), statusBar(), SLOT(showMessage(QString)));@

      Hope it helps

      EDIT:forgot showMessage QString parameter

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • M Offline
        M Offline
        Max13
        wrote on last edited by
        #3

        [quote author="SGaist" date="1365676850"]Hi,
        Why not have your ConnectionWidget emit a signal with a QString parameter and connect it to the QMainWindow statusbar slot showMessage() ?
        [/quote]

        Actually, this is what I did first. The thing is I want to handle general status like "Ready" and temporary status like "Field can't be empty", and when the temporary is cleared, I show back the last message. I have a QString attribute to store it in the MainWindow. If I connect directly the parent's statusBar, I have to implement the "last message" system in the children which is not logical for me.

        Thank you anyway.

        We all have started by asking questions. Then after some time, we can begin answering them.

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Field empty error should be shown directly besides your mandatory input, it would be clearer for the user.

          As for managing temporary/constant message, if your temporary message are "time based" you can use showMessage(myString, myTimeoutValue). If it's a bit more complex you can either make a QStatusBar subclass and handle that there, make an object that is a "man in the middle" that handles that, or use your MainWindow for that purpose.

          Hope it helps

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • M Offline
            M Offline
            Max13
            wrote on last edited by
            #5

            This is the point, I want to know if there is a "common" or "classic" pattern for this sort of interactions.

            Currently, here is what I have:
            @// ConnectionWidget.hpp
            signals:
            void changeStatus(QString message, int timeout);@

            @// ConnectionWidget.cpp
            connect(this, SIGNAL(changeStatus(QString, int)),
            this->m_parent->statusBar(), SLOT(showMessage(QString, int)));
            emit this->changeStatus("Ready", 0);@

            @ // MainWindow.cpp
            if (timeout)
            this->m_oldStatusMessage = this->statusBar()->currentMessage();
            else
            this->m_oldStatusMessage.clear();
            this->statusBar()->showMessage(message, timeout);@

            The thing here is that the children have to connect themselves to the parent status bar, my question is more "is it a good way to do it" instead for example, make the parent listen to the children signals ? The correct way to make this. Parent listen child(ren), Children connect to parent, delegate, ...?

            Thank you for your answers.

            We all have started by asking questions. Then after some time, we can begin answering them.

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Make these connections in MainWindow.

              ConnectionWidget should not care of where the signal is going. On the other hand MainWindow knows what to do with this signal so it's his job to do the connection.

              This keeps your classes decoupled.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • M Offline
                M Offline
                Max13
                wrote on last edited by
                #7

                Here we are. If the MainWindow makes the connection itself, it means it has to know the type of the child.

                As the "childs" are subclasses of QWidget, do I have to subclass QWidget to add the signals ? Then force MainWindow to only accept "MyOwnWidget *" by overloading "setCentralWidget" ?

                I ask this because if I don't do this (which complicates my code) I don't know how to listen for the "setCentralWidget" to avoid trying to connect to empty centralWidget.

                Thank you :)

                We all have started by asking questions. Then after some time, we can begin answering them.

                1 Reply Last reply
                0
                • B Offline
                  B Offline
                  b1gsnak3
                  wrote on last edited by
                  #8

                  well... didn't you say that connectionwidget is your subclass of QWidget, which is your centralWidget? If you trully are worried about this, you could check to see if QMainWindow::centralWidget() != 0, because "documentation":http://qt-project.org/doc/qt-4.8/qmainwindow.html#centralWidget says that it will return 0 when no widget has been set

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    Max13
                    wrote on last edited by
                    #9

                    [quote author="b1gsnak3" date="1365687201"]well... didn't you say that connectionwidget is your subclass of QWidget, which is your centralWidget?[/quote]
                    Hey, you're focused, I like it =P

                    Yes I did, my ConnectionWidget is a subclass of QWidget, it's intended to be a central widget but not the only one. That's why I'm stuck here. I have to find a way to let children handle the message easily.

                    Thanks anyway.

                    We all have started by asking questions. Then after some time, we can begin answering them.

                    1 Reply Last reply
                    0
                    • B Offline
                      B Offline
                      b1gsnak3
                      wrote on last edited by
                      #10

                      Ok. But be careful because setting a new central widget will delete the old one. As to your problem, please, if you can, explain again to me because I can't understand from bits and pieces xD

                      1 Reply Last reply
                      0
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        If you have multiple widgets that will go as "central widget", you might be interested by QStackedWidget. Have all your widgets in the stack and show the right widget at the right time.

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply
                        0
                        • M Offline
                          M Offline
                          Max13
                          wrote on last edited by
                          #12

                          [quote author="b1gsnak3" date="1366008052"]Ok. But be careful because setting a new central widget will delete the old one.[/quote]

                          Yup, thanks. I always @delete this->centralWidget();@


                          [quote author="SGaist" date="1366010452"]you might be interested by QStackedWidget.[/quote]
                          Unfortunately, I forgot about it and did something ugly, but really efficient for my case.

                          I re-explain for b1gsnak3: I want a simple and easy system to change my centralWidget and listen to the child "changeStatus" to route it to statusBar()->showMessage(). I did it my way at the beginning (connection in children, bad), but someone (Objective-C dev) told me about the delegates but I wanted C++ dev advices.

                          Here is what I did:

                          I've created my own "AbstractWidget" which has a pure virtual slot (nextWidgetAction()), which what the children have to call when they've done their job (Database connection for example).

                          "nextWidgetAction()" must actually create a new widget, which is the next widget the parent have to show in its centralWidget, and emit the signal "widgetJobFinished(AbstractWidget *newWidget)".

                          The parent is listening to widgetJobFinished() and call setCentralWidget with the parameter.

                          I've overloaded "setCentralWidget()" in my MainWindow to take only "AbstractWidget *", to be able to pass it any of my subclassed widgets.

                          In "setCentralWidget(AbstractWidget *)", I delete "this->m_centralWidget;" (which is my subclassed current widget).

                          Then I call "QMainWindow::setCentralWidget(newWidget);" to set my new centralWidget, store it in my MainWindow and listen to the newWidget's slot "widgetJobFinished(AbstractWidget *)".

                          It's not really nice to do that way, but to combine a system where the MainWindow can't know in advance which "type" of widget it has to show when and change the statusBar() correctly, the best way for me was to initialize IN the children the following widget (for i.e.: "welcomeWidget" inits "databaseConnection" which inits "queryWidget") and obviously the widgets can't show backwards (the old are deleted) and there is no need.

                          What do you think about that ?

                          We all have started by asking questions. Then after some time, we can begin answering them.

                          1 Reply Last reply
                          0
                          • SGaistS Offline
                            SGaistS Offline
                            SGaist
                            Lifetime Qt Champion
                            wrote on last edited by
                            #13

                            Isn't that some sort of QWizard you are writing ?

                            Interested in AI ? www.idiap.ch
                            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                            1 Reply Last reply
                            0
                            • M Offline
                              M Offline
                              Max13
                              wrote on last edited by
                              #14

                              [quote author="SGaist" date="1366014252"]Isn't that some sort of QWizard you are writing ?[/quote]
                              Hum... Now you mention it, yes it is :/
                              But I don't need the ability to go backward, but except that, it could be a QWizard.

                              We all have started by asking questions. Then after some time, we can begin answering them.

                              1 Reply Last reply
                              0
                              • B Offline
                                B Offline
                                b1gsnak3
                                wrote on last edited by
                                #15

                                1st. For your setCentralWidget I would do it like:

                                @
                                if(this->centralWidget() != 0) delete this->centralWidget();
                                @

                                2nd. You could've used just one class, with an Enum of properties (which you set when you instantiate the properties) that would be your different types of action your widget needs to do and according to those properties create your widgets and call different methods (or use different constructors for each type of widget). And you would've had one big class instead of multiple ones.

                                1 Reply Last reply
                                0
                                • M Offline
                                  M Offline
                                  Max13
                                  wrote on last edited by
                                  #16
                                  1. I think you can delete multiple times "NULL" but not an already deleted pointer. So checking if NULL won't guaranty me to delete an allocated space. Anyway, I have the habits to do like this EVERY TIME, to be safe, and to be able to delete it again and again if I try to delete a pointer passed by a parent for example:
                                    @ptr = new ...;
                                    delete ptr;
                                    ptr = NULL;@

                                  2. I could do like that, but I wanted my MainWindow completely unaware of the children, as a QMainWindow would. So it means, every time I want a new widget, I just have to create it in the previous child and pass it in the SIGNAL. Then I don't need to modify the MainWindow class, and I will have multiple children because anyway, these children will have their own job and so their own class. Isn't it ?

                                  We all have started by asking questions. Then after some time, we can begin answering them.

                                  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