Set Qlabel from another thread.
-
When I try to set text of a label from another thread I get this error Cannot send events to objects owned by a different thread. Current thread 376e328. Receiver '' (of type 'QTextDocument') was created in thread.How to fix it?
-
Use the signal/slot method and give the text of the label as parameter. That should do the trick!
-
Can you give an example.
-
@
QObject::connect(this, SIGNAL(setLabelText(const QString &)), label, SLOT(setText(const QString &), Qt::QueuedConnection);
@ -
When I try to use setLabelText it says"identifier not found ".
-
I coded up an example. From there you should be able to figure out your error. Sorry, documentation not included. Note that this app has at least one bug ( QThread can be destroyed while the thread still running ), but your question wasn't about thread startup/shutdown.
Counter.h
@
#ifndef COUNTER_H
#define COUNTER_H
#include <QObject>class Counter : public QObject
{
Q_OBJECT
public:
explicit Counter(QObject *parent = 0);signals:
void setLabelText( const QString& newValue );
void finished();public slots:
void countto10();
};
#endif // COUNTER_H
@Counter.cpp
@
#include "counter.h"
#include <QThread>Counter::Counter(QObject *parent) :
QObject(parent)
{
}void Counter::countto10()
{
for ( int i = 1; i <= 10; ++i )
{
emit setLabelText( QString::number(i) );
QThread::sleep( 1 );
}
emit setLabelText( tr("Done") );
emit finished();
}
@Window.h
@
#ifndef WINDOW_H
#define WINDOW_H#include <QWidget>
#include <QLabel>class Window : public QWidget
{
Q_OBJECT
public:
Window(QWidget *parent = 0);
private:
QLabel *textLabel;
};#endif
@Window.cpp
@
#include <QtWidgets>
#include "window.h"
#include "counter.h"Window::Window(QWidget *parent)
: QWidget(parent)
{
textLabel = new QLabel(tr("I am a text label"));
QGridLayout *mainLayout = new QGridLayout;
mainLayout->setSizeConstraint(QLayout::SetNoConstraint);
mainLayout->addWidget(textLabel, 1, 0);
setLayout(mainLayout);QThread* thread = new QThread(this); Counter* counter = new Counter(); counter->moveToThread(thread); connect(thread, SIGNAL(started()), counter, SLOT(countto10())); connect(counter, SIGNAL(finished()), thread, SLOT(quit())); connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); connect( counter, SIGNAL(setLabelText(QString)), textLabel, SLOT(setText(QString)) ); thread->start();
}
@Main.cpp
@
#include <QApplication>#include "window.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Window window;
window.show();
return app.exec();
}
@ -
I sill have and problem - it doesn't work.
@
...
CursorListener *cursorWorker;
...
someMethod()
{
emit setLabelText(qstr);
}
...
connect(cursorWorker, SIGNAL(setLabelText(const QString &)), myBrowser, SLOT(setText(const QString &)));
....
@
when I call someMethod my Browser doesn't change its text. -
The problem is relatively straightforward, so there are only a few possibilities that I can see.
- The connect() method isn't being called prior to someMethod() being called.
- The setLabelText() signal definition is not correct.
- The connect() function is being called with parameters that fail at run time.
- The connection is being disconnected elsewhere in the code
- Some other problem is occurring in the source code that we cannot see.
If you're using Qt5, you can use the new connect() syntax to find errors at compile time in #2 or #3. See here:
http://qt-project.org/doc/qt-5.0/qtdoc/qt5-intro.html#new-connection-syntax
or here:
http://qt-project.org/wiki/New_Signal_Slot_Syntax
or even here:
http://woboq.com/blog/how-qt-signals-slots-work-part2-qt5.htmlOther than that, there's not a lot of help I can give. "It doesn't work" with 10 lines of source is not much to go on.