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. [SOLVED] update message display from another thread
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] update message display from another thread

Scheduled Pinned Locked Moved General and Desktop
13 Posts 4 Posters 5.4k Views 1 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.
  • U Offline
    U Offline
    user001
    wrote on last edited by
    #1

    I have a QDialog to display some message with QLabel and QString. I need to update the message, replace the QString or append the newer. The message is from another QThread which is doing some calculation. And the calculation is triggered by a button on the dialog.

    I want the message being updated immediately when new result is available and there are many results come out at different time.

    Quesitons:

    1. QString and QLabel are right widgets for this purpose? message will not be very long.
    2. read online the QLabel::repaint() will update the display but it cannot be triggered from another thread. Qt will throw: Cannot send events to objects owned by a different thread. Without the repaint() call, the label will be updated at the end of all results are available. In Java there are Event Dispatcher thread and Worker thread. Qt may has similar things. Then what's the right way to update GUI display from other thread?
    1 Reply Last reply
    0
    • D Offline
      D Offline
      dbzhang800
      wrote on last edited by
      #2

      [quote author="user001" date="1373986405"]

      1. QString and QLabel are right widgets for this purpose? message will not be very long.
        [/quote]
        Yes they are.

      [quote author="user001" date="1373986405"]

      1. read online the QLabel::repaint() will update the display but it cannot be triggered from another thread. Qt will throw: Cannot send events to objects owned by a different thread. Without the repaint() call, the label will be updated at the end of all results are available. In Java there are Event Dispatcher thread and Worker thread. Qt may has similar things. Then what's the right way to update GUI display from other thread?[/quote]

      2. You never need to call of repaint() member of QLabel, QLabel::setText() is enough.

      3. If you find that QLabel doesn't get updated after setText(), there must be something wrong in other place. which cause your main thread get blocked.

      4. Make your object in sub-thread emit a signal with QString as parameter, connect this signal to your QLabel's setText() slot.

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

        Hi,

        Have a look at the MandelBrot example, It will help you understand how to achieve what you want to do.

        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
        • U Offline
          U Offline
          user001
          wrote on last edited by
          #4

          [quote author="1+1=2" date="1373987064"]

          1. You never need to call of repaint() member of QLabel, QLabel::setText() is enough.
          2. If you find that QLabel doesn't get updated after setText(), there must be something wrong in other place. which cause your main thread get blocked.
          3. Make your object in sub-thread emit a signal with QString as parameter, connect this signal to your QLabel's setText() slot.[/quote]

          It will not update the display until the end of the calculation if repaint() is not called.

          I didn't use signal. I called a updateMessage(QString) which will do setText() and repaint() (if needed) from the calculation thread.

          I will try signal then.

          1 Reply Last reply
          0
          • U Offline
            U Offline
            user001
            wrote on last edited by
            #5

            By following mandelbrot example, i cannot make it works. The signal is not passed to slot. Following are those code:

            @#ifndef MYMSGTHREAD_H
            #define MYMSGTHREAD_H

            #include <QThread>

            class MyMsgThread : public QThread
            {
            Q_OBJECT
            public:
            MyMsgThread( QObject *parent = 0);

            signals:
            void newMsgAvailable(const QString&);
            void msgEnded();

            private:
            void run();
            void newMsg(QString);

            };

            #endif // MYMSGTHREAD_H@

            @#ifndef EXITDIALOG_H
            #define EXITDIALOG_H

            #include <QDialog>

            #include "../uiscreen.h"
            #include "../msgthread/mymsgthread.h"

            class QPushButton;
            class QString;
            class QLabel;

            class ExitDialog : public QDialog, public UiScreen
            {
            Q_OBJECT

            public:
            ExitDialog(MainWindow *mWindow);
            ~ExitDialog();

            virtual ReturnStatus showMe();
            virtual ReturnStatus hideMe();
            virtual ReturnStatus disposeMe();
            

            private:
            virtual ReturnStatus init();

            ReturnStatus showDialog();
            ReturnStatus confirmAgain();
            void createUI();
            
            
            QLabel *label;
            QPushButton *yesBtn;
            QPushButton *sureYesBtn;
            QPushButton *noBtn;
            QPushButton *updateMsgBtn;
            QString msg;
            bool msgUpdated;
            MyMsgThread myThread;
            

            private slots:
            void yesBtnClicked();
            void sureYesBtnClicked();
            void noBtnClicked();
            void updateMsgBtnClicked();
            void msgEnded();
            void updateMsg(const QString&);
            };

            #endif // EXITSCREEN_H@

            connect is done in ExitDialog::init()
            @ReturnStatus ExitDialog::init()
            {
            ReturnStatus status = ReturnStatus::Success;
            createUI();
            connect(&myThread, SIGNAL(newMsgAvailable(const QString&)), this, SLOT(updateMsg(const QString&)));
            connect(&myThread, SIGNAL(msgEnded()), this, SLOT(msgEnded()));

            cout << "ExitDialog::init()" << endl;
            return status;
            

            }@

            when updateMsgBtnClicked() is called, it will start() MyMsgThread. newMsgAvailable() will be emitted like this:

            @void MyMsgThread::newMsg(QString msgAvailable)
            {
            cout << "MyMsgThread::newMsg() msg=" << msgAvailable.toStdString() << endl;
            emit newMsgAvailable(msgAvailable);
            }@

            which is called from the MyMsgThread::run(). From the print out I can see the newMsg() method is called several times.

            Suppose the updateMsg(), which is the slot associated with newMsgAvailable(), will be triggered by the messaging system of Qt. But it is not here. Can you see anything wrong with my code?

            the UiScreen class is a regular abstract class (not a QObject) which defines some abstract methods.

            1 Reply Last reply
            0
            • M Offline
              M Offline
              MaximAlien
              wrote on last edited by
              #6

              Your slots are private, make them public, it may fix the problem.

              1 Reply Last reply
              0
              • U Offline
                U Offline
                user001
                wrote on last edited by
                #7

                [quote author="MaximAlien" date="1374001473"]Your slots are private, make them public, it may fix the problem.[/quote]

                I tried that before. I tested again with clean, build and run. Problem is still there.

                @public slots:
                void msgEnded();
                void updateMsg(const QString&);@

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  MaximAlien
                  wrote on last edited by
                  #8

                  I think @MyMsgThread myThread;@ must be pointer @MyMsgThread *myThread;@ And you'll connect it like that:

                  @connect(myThread, SIGNAL(newMsgAvailable(const QString&)), this, SLOT(updateMsg(const QString&)));
                  connect(myThread, SIGNAL(msgEnded()), this, SLOT(msgEnded()));@

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

                    Of course it has to be created using @new@ opertator.

                    1 Reply Last reply
                    0
                    • U Offline
                      U Offline
                      user001
                      wrote on last edited by
                      #10

                      I found the problem. I have a while loop in the ExitDialog after started the thread. It is that loop blocked the GUI thread. My fault. Thank you for your help.

                      1 Reply Last reply
                      0
                      • M Offline
                        M Offline
                        MaximAlien
                        wrote on last edited by
                        #11

                        Great, Please mark your topic as SOLVED

                        1 Reply Last reply
                        0
                        • U Offline
                          U Offline
                          user001
                          wrote on last edited by
                          #12

                          How can I make it as solved?

                          1 Reply Last reply
                          0
                          • M Offline
                            M Offline
                            MaximAlien
                            wrote on last edited by
                            #13

                            On the top of this thread there is EDIT link, press it and you'll be able to edit your topic. Simply write [solved] update message display from another thread.

                            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