[SOLVED] update message display from another thread
-
Hi,
Have a look at the MandelBrot example, It will help you understand how to achieve what you want to do.
-
[quote author="1+1=2" date="1373987064"]
- You never need to call of repaint() member of QLabel, QLabel::setText() is enough.
- 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.
- 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.
-
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_OBJECTpublic:
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.
-
Your slots are private, make them public, it may fix the problem.
-
[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&);@ -
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()));@ -
Of course it has to be created using @new@ opertator.
-
Great, Please mark your topic as SOLVED
-
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.