What does it mean to move a object from one thread to another in Qt using moveToThread? Everything seems to work even before using moveToThread, which moves the object from one thread (GUI thread) to a another thread ( worked) and Qt:connect calls the appropriate slot on object.
Is there any difference because of where the object lives, GUI thread or the worker thread?
EDIT:
I made a small program, but I don’t understand how QThread works along with Signal and slot function, I would appreciate if you could explain what is the use of moveToThread with the example
#include <QtGui/QApplication>
#include <QPushButton>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QString>
#include "mythread.h"
//GUI calls a thread to do some job and sub update the text box once it is done
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
QHBoxLayout * pH = new QHBoxLayout(&w);
QPushButton * pushButton = new QPushButton("asdad");
QLineEdit * lineEdit = new QLineEdit("AAA");
pH->addWidget(pushButton);
pH->addWidget(lineEdit);
w.setLayout(pH);
w.show();
MyThread thread;
qDebug("Thread id %d",(int)QThread::currentThreadId());
QObject::connect(pushButton,SIGNAL(clicked()),&thread,SLOT(callRun())) ;
QObject::connect(&thread,SIGNAL(signalGUI(QString)),lineEdit,SLOT(setText(QString)));
return a.exec();
}
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QMutex>
class MyThread : public QThread
{
Q_OBJECT
public:
MyThread();
public slots:
void callRun();
void run();
signals:
void signalGUI(QString);
private:
QMutex mutex;
};
#endif // MYTHREAD_H
#include "mythread.h"
#include <QDebug>
#include <QString>
#include <QMutexLocker>
MyThread::MyThread()
{
}
void MyThread::callRun()
{
qDebug("in thread");
if(!isRunning())
{
this->start(LowestPriority);
exec();
}
else
{
run();
}
}
void MyThread::run()
{
QMutexLocker fn_scope(&mutex);
static int a = 0;
++a;
qDebug("Thread id inside run %d",(int)QThread::currentThreadId());
this->sleep(3);
static QString number;
QString temp;
number += temp.setNum(a);
emit signalGUI(number);
}
Take a look at Signals and slots across threads. If you always use signals and slots to communicate with the worker thread, Qt handles the moveToThread for you if it’s needed and you used the correct connection.
Edit: I would guess the article’s author was seeing his problem since he was calling start in the constructor before the thread was actually created. In other words, don’t trust third-party code blindly.
Edit: In response to your comment, look at the Mandelbrot example, under the
MandelbrotWidget Class Implementationheader:I believe this is slightly outdated, here are the valid meta types. Since signals and slots across threads use queued connections, you should not have to do the moveToThread calls in most cases.
Edit:
I will try to explain things with a similar example:
mythread.h:
mythread.cpp:
mylineedit.h
mylineedit.cpp
main.cpp:
Sample output after clicking button:
As you can see, the run thread is different than the main GUI thread. Also, even though you pass a const reference to a QString, since it crosses thread boundaries it copies it.
I strongly encourage you to read Threads and QObject.