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.6k 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 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