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. proper separation of worker and widget
Qt 6.11 is out! See what's new in the release blog

proper separation of worker and widget

Scheduled Pinned Locked Moved Solved General and Desktop
15 Posts 4 Posters 3.5k 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.
  • mzimmersM Offline
    mzimmersM Offline
    mzimmers
    wrote on last edited by
    #1

    Hi all -

    I'm writing a small program with 2 primary objects: a worker and a widget. These are not in separate threads.

    I'm often finding myself needing to pass information between the two, and I've been using signals for this, perhaps improperly. One example of something I've done that just doesn't look right is the notification of the worker when a combo box changes. Since the combo box is a member of my widget class, I'm doing this:

    CdWidget::CdWidget(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::Widget)
    {
        ui->setupUi(this);
        connect(ui->comboBox, SIGNAL(activated(QString)), this, SLOT(on_comboBox_currentIndexChanged(QString)));
    }
    ...
    void CdWidget::on_comboBox_currentIndexChanged(const QString &portName)
    {
        emit comPortChanged(portName);
    }
    

    and in main() I do this:

        QObject::connect(&w, &CdWidget::comPortChanged, &s, &CdSerial::setComPort);
    

    Seems like I'm adding an unnecessary level of complexity, but I don't know how to go about resolving it. Any suggestions? Thanks.

    kshegunovK 1 Reply Last reply
    0
    • mzimmersM mzimmers

      Hi all -

      I'm writing a small program with 2 primary objects: a worker and a widget. These are not in separate threads.

      I'm often finding myself needing to pass information between the two, and I've been using signals for this, perhaps improperly. One example of something I've done that just doesn't look right is the notification of the worker when a combo box changes. Since the combo box is a member of my widget class, I'm doing this:

      CdWidget::CdWidget(QWidget *parent) :
          QWidget(parent),
          ui(new Ui::Widget)
      {
          ui->setupUi(this);
          connect(ui->comboBox, SIGNAL(activated(QString)), this, SLOT(on_comboBox_currentIndexChanged(QString)));
      }
      ...
      void CdWidget::on_comboBox_currentIndexChanged(const QString &portName)
      {
          emit comPortChanged(portName);
      }
      

      and in main() I do this:

          QObject::connect(&w, &CdWidget::comPortChanged, &s, &CdSerial::setComPort);
      

      Seems like I'm adding an unnecessary level of complexity, but I don't know how to go about resolving it. Any suggestions? Thanks.

      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by kshegunov
      #2

      on_comboBox_currentIndexChanged is just superfluous.

      connect(ui->comboBox, SIGNAL(activated(const QString &)), this, SIGNAL(comPortChanged(const QString &)));
      

      or if you're using Qt 5, which you should:

      connect(ui->comboBox, &QComboBox::activated, this, &CdWidget::comPortChanged);
      

      Read and abide by the Qt Code of Conduct

      1 Reply Last reply
      2
      • mzimmersM Offline
        mzimmersM Offline
        mzimmers
        wrote on last edited by
        #3

        @kshegunov said in proper separation of worker and widget:

        comPortChanged

        But comPortChanged is part of the worker object, not the widget.
        It's as though I need a containing object that can "connect" the widget and the worker, but I imagine there's a better way to do this that I'm not aware of.

        kshegunovK 1 Reply Last reply
        0
        • mzimmersM mzimmers

          @kshegunov said in proper separation of worker and widget:

          comPortChanged

          But comPortChanged is part of the worker object, not the widget.
          It's as though I need a containing object that can "connect" the widget and the worker, but I imagine there's a better way to do this that I'm not aware of.

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by
          #4

          @mzimmers said in proper separation of worker and widget:

          But comPortChanged is part of the worker object, not the widget.

          Not according to your code:

          QObject::connect(&w, &CdWidget::comPortChanged, &s, &CdSerial::setComPort);
          

          Read and abide by the Qt Code of Conduct

          1 Reply Last reply
          0
          • mzimmersM Offline
            mzimmersM Offline
            mzimmers
            wrote on last edited by
            #5

            I'm sorry for the ambiguity -- CdSerial is my worker class. I need a signal from an object in CdWidget (the combo box) to signal CdSerial.

            int main(int argc, char *argv[])
            {
                 QApplication a(argc, argv);
                CdWidget w;
                CdSerial s;
            ...
                QObject::connect(&w, &CdWidget::comPortChanged, &s, &CdSerial::setComPort);
            ...
            

            I may not be going about this the right way...

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

              Hi,

              From the looks of it, you have a signal named comPortChanged in CdWiget, so @kshegunov just suggested to use signal forwarding by connecting your QComboBox signal to your CdWidget signal.

              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
              1
              • mzimmersM Offline
                mzimmersM Offline
                mzimmers
                wrote on last edited by
                #7

                Sorry, guys - my statement above was wrong. (Trying to solve too many issues at once.)

                So, apart from my unnecessary step, do I correctly understand the proper technique as:

                1. comboBox signals CdWidget
                2. CdWidget signals CdSerial

                I can imagine this producing a ton of connects in larger projects. Is this a sign of bad design on my part?

                Thanks...

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

                  No, that keeps your different pieces cleanly separated.

                  Your CdWidget provides a signal that says: "com port name has changed". It's comPortChanged. You connect that signal on your CdSerial object -> simple and clean and done in main.cpp.

                  Internally in CdWidget, you forward your combobox's indexChanged to the comPortChanged signal -> simple and clean. You could be using something else to select the com port name and maybe have to use a private slot before calling comPortChanged. That would also be OK. The advantage of doing this is that you can easily change CdWidget's internal without disrupting the rest of your code.

                  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
                  2
                  • mzimmersM Offline
                    mzimmersM Offline
                    mzimmers
                    wrote on last edited by
                    #9

                    OK, thanks guys. Good education. I also didn't realize you could connect a signal to a signal as @kshegunov did in his example.

                    J.HilkJ 1 Reply Last reply
                    0
                    • mzimmersM mzimmers

                      OK, thanks guys. Good education. I also didn't realize you could connect a signal to a signal as @kshegunov did in his example.

                      J.HilkJ Online
                      J.HilkJ Online
                      J.Hilk
                      Moderators
                      wrote on last edited by
                      #10

                      @mzimmers QObject::connect is a very, very powerful tool. with Qt5 and c++ 11 you can even connect a lambda function to any Signal:

                      //Example taken directly from the wiki
                      connect(    sender, &Sender::valueChanged,  [=]( const QString &newValue ) { receiver->updateValue( "senderValue", newValue ); }
                      );
                      

                      If you pass Connect the receiver as reference you will not have to worry about clean up either

                      connect(    sender, &Sender::valueChanged,  receiver, [=]( const QString &newValue ) { receiver->updateValue( "senderValue", newValue ); }
                      
                      ...
                      // receiver gets deleted
                      receiver->deleteLater();
                      
                      ....
                      //No crash
                       emit valueChanged("STRING);
                      
                      

                      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.

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

                        @J-Hilk In the case at hand a lambda is really overkill.

                        Out of curiosity, what wiki page shows that ?

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

                        J.HilkJ 1 Reply Last reply
                        0
                        • SGaistS SGaist

                          @J-Hilk In the case at hand a lambda is really overkill.

                          Out of curiosity, what wiki page shows that ?

                          J.HilkJ Online
                          J.HilkJ Online
                          J.Hilk
                          Moderators
                          wrote on last edited by
                          #12

                          @SGaist said in proper separation of worker and widget:

                          @J-Hilk In the case at hand a lambda is really overkill.

                          Out of curiosity, what wiki page shows that ?

                          I have the example from here:
                          https://wiki.qt.io/New_Signal_Slot_Syntax


                          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.

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

                            Ok, thanks.

                            However what you are citing, AFAIK, is a reflection regarding the handling of lambda disconnection.

                            From QObject's documentation there's no overload matching your proposed connect statement.

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

                            J.HilkJ 1 Reply Last reply
                            0
                            • SGaistS SGaist

                              Ok, thanks.

                              However what you are citing, AFAIK, is a reflection regarding the handling of lambda disconnection.

                              From QObject's documentation there's no overload matching your proposed connect statement.

                              J.HilkJ Online
                              J.HilkJ Online
                              J.Hilk
                              Moderators
                              wrote on last edited by
                              #14

                              @SGaist
                              are you sure? Isn't this one fitting?

                              connect(const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type)
                              

                              However it works that way take this simple example:

                                  QPushButton * pushButton = new QPushButton();
                                  pushButton->show();
                                  QObject *obj = new QObject();
                              
                                  connect(pushButton, &QPushButton::clicked,obj,[=]{
                                      QLabel * lbl = new QLabel();
                                      lbl->show();
                                      lbl->setText(QTime::currentTime().toString());
                                      connect(qApp,&QApplication::aboutToQuit, lbl,&QLabel::deleteLater);
                                      obj->deleteLater();
                                  });
                              

                              Only 1 Lable will appear no mater how often you press the Button


                              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.

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

                                Completely my bad, I missed that one and the worse is that I remember now reading earlier this year about it !

                                Thanks for pointing it out :)

                                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
                                1

                                • Login

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