PDA

View Full Version : Simple QThread class and QObject::moveToThread() - questions



_franko_
16th March 2011, 21:15
Hi all,

I'm new to threading in Qt.
I have several questions regarding the following class. I hope that wise programmers of this forum will help me better understand the QThread class and how does threads works in Qt.

thread1.h


#ifndef THREAD1_H
#define THREAD1_H

#include <QThread>
#include <QTimer>

class Thread1 : public QThread
{
Q_OBJECT
public:
Thread1();
~Thread1();

protected:
void run();

signals:
void sigThreadQuit();

public slots:
void sTimeout();

private:
QTimer* timer1;
QTimer timer2;

int counter;
};

#endif // THREAD1_H


thread1.cpp


#include "thread1.h"

Thread1::Thread1():
timer1(new QTimer(this)), counter(0)
{
qDebug("Thread1(): Creating...");
timer1->setInterval(1000);
timer2.setInterval(1000);

connect(timer1, SIGNAL(timeout()), this, SLOT(sTimeout()));
connect(&timer2, SIGNAL(timeout()), this, SLOT(sTimeout()));

moveToThread(this);
}

Thread1::~Thread1() {
qDebug("~Thread1(): Destroyed.");
}

void Thread1::run() {
qDebug("Thread1::run(): Running...");
timer1->start();
timer2.start();
exec();
}

void Thread1::sTimeout() {
QTimer* t = (QTimer*) sender();
qDebug("sTimeout(): Timer: %p; Counter: %d", t, counter);
if(counter > 10)
emit sigThreadQuit();
counter++;
}


main.cpp


#include <QtCore/QCoreApplication>

#include "thread1.h"
#include "thread2.h"

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug("Main start");

// Thread1* t1 = new Thread1();

Thread1 t2;

// Thread2 t2;

// a.connect(t1, SIGNAL(sigThreadQuit()), &a, SLOT(quit()));
a.connect(&t2, SIGNAL(sigThreadQuit()), &a, SLOT(quit()));

// t1->start();
t2.start();

int retvel = a.exec();

qDebug("Main end");
return retvel;
}


The main function creates an object of class Thread1, which is designed to display text and after 10 seconds to send a signal to finish the thread.
After creating a t2 object, signal sending by a thread is connected with the slot quit() of the main application.
In the above class, I have two objects QTimer - one of them is a pointer.
After running the application I see that only one timer is working - a pointer.

Here are my questions:
1. Why I can not see the operation of the QTimer object which is not a pointer? Does is not running?
2. If I don't use function moveToThread() for instance in the constructor of Thread1 class, then QTimer objects (or a thread), do not start in general. I think that it has something with main a.exec() function. Why and what?
3. Does the above example is written correctly with the principles of multithreaded programming in Qt?

I wrote this class for understanding Qt thread support. Any posts with good explanations and links are welcome.

Thank you for any answers :)

MarekR22
17th March 2011, 09:28
1. Never ever move thread to it self! Moving QObject to thread means that connected (see Qt::ConnectionType-enum) slots will be run in thread they were move to!
2. moveToThread works only when object doesn't have a parent! See QObject::moveToThread

3. Read this (http://labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong/)

_franko_
17th March 2011, 14:30
Thank you for your post.

Third answer has me thinking. So now I have to redesign my class and read once again docs and tutorials carefully.

Thanks.