PDA

View Full Version : QThread and QTimer



bibhukalyana
23rd September 2013, 12:42
Hi everyone,
I have one GUI class, one thread class, and one timer inside thread class.

mainwindow.h file:



class testClass : public QThread
{
Q_OBJECT
public:
testClass();
void run();
public slots:
void timerExpired();
void startWork();

private:
QTimer *timer;
};

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

signals:
void startSignal();

private slots:
void on_pushButton_clicked();

private:
Ui::MainWindow *ui;
};



mainwindow.c



void MainWindow::on_pushButton_clicked()
{
emit startSignal();
}


testClass::testClass()
{}

void testClass::run()
{
timer = new QTimer();
QObject::connect(timer,SIGNAL(timeout()),this,SLOT (timerExpired()),Qt::DirectConnection);
exec();
}

void testClass::startWork()
{
timer->start(0);
}

void testClass::timerExpired()
{
qDebug("Timer expired.");
}



main.cpp



int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
testClass tCls;
QObject::connect(&w,SIGNAL(startSignal()),&tCls,SLOT(startWork()),Qt::QueuedConnection);
w.show();
tCls.start(QThread::NormalPriority);

return a.exec();
}


In this case I am getting a run time error "QObject::startTimer: timers cannot be started from another thread".

What I understood :

timer is allocated inside run() so it belogs to testClass thread.But when i was trying to call the testClass::startWork() slot from mainwindow at that time testClass::startWork() belongs to mainwindow thread. So the timer is not able to start.
If I will take timer as static(from stack) then it will be fine because timer will be in main thread.

What i have mentioned here is it true ?
Is the member function of testClass belongs to testClass thread or not ?
I am using signal slot to communicate between two thread .But the current thread id of mainwindow and startWork() slot are same.
How i solve this ?

thanks.

saman_artorious
23rd September 2013, 13:28
why do you need a timer inside a thead!!! you can trigger the segment you are willing to trigger with the thread itself.

wysota
23rd September 2013, 13:38
What i have mentioned here is it true ?
Yes.


Is the member function of testClass belongs to testClass thread or not ?
Functions do not belong to threads. Only objects do in the sense that a thread processes events of an object.


I am using signal slot to communicate between two thread .But the current thread id of mainwindow and startWork() slot are same.
That's because the QThread instance lives in the main thread so its slots are executed in the context of the main thread.


How i solve this?

Instead of subclassing QThread, create an instance of it, wrap the functionality you want into a QObject instance and move that object into the thread.



QThread t;
t.start();
Object *o = new Object;
o->moveToThread(&t);
connect(mainWin, SIGNAL(someSignal()), o, SLOT(doSomeWork()));

bibhukalyana
23rd September 2013, 14:16
Thanks for reply.

I tried like :



testClass *tCls = new testClass();

QThread t;
t.start();
tCls->moveToThread(&t);

QObject::connect(&w,SIGNAL(startSignal()),tCls,SLOT(startWork()),Qt: :QueuedConnection);
w.show();


I am getting segmentation fault.
Or will I take one more class and inherits QThread and after that execute movetoThread.

One more thing. It is working but I dont know this is corret or not .



tCls->moveToThread(tCls);
tCls->start(QThread::NormalPriority);


thanks.

wysota
23rd September 2013, 14:23
testClass should inherit QObject and not QThread, that's for sure. If your program crashes then find the crash.

bibhukalyana
23rd September 2013, 14:47
thanks it is my mistake.

Can you please tell me how to assing memory to timer so that it will belong to testClass thread ?
If after moveToThread i tried to call directly using object, but i get the same error.
But current thread id of startWork() and mainclass are different (thanks.. It is working).

wysota
23rd September 2013, 14:59
You can never call the timer directly if you want it to be part of an object living in a different thread.