PDA

View Full Version : QTimer in a worker thread



inger
3rd February 2012, 08:32
Hi,

I have problems with starting a QTimer or singleshot in a worker thread. Is that true that the timers only will start in the main thread?

My main start an object startIntegrator, that is a QObject. This object start a new thread called FB_thread (QThread). The run() of this thread go to a function , called receiveMsg(), that check if something come to a defined com-port. I want to count these incomming bytes. I want to start a timer when the run()-function receive something. When this timer timeout(), I want to put the counter to zero.

I want to put the reading function in a thread because I will have several threads to read an put into several queues.
My communication procedure with the commPort is qextserialcommport.

In addition to that timer mentioned, I want to start a timer that go into FB_thread's .
I use Ubuntu OS.

My question is:
Where do I put the counter, and how?

I have tried several places in my program, but the Timer will not be set to zero.
My last try is like this:

startIntegrator::startIntegrator(QObject *parent) :
QObject(parent)
{
FB_thread = new Flex_thread;
FB_thread->start();

flexiTimer = new QTimer();
flexiTimer->setInterval(5);
flexiTimer->start();

connect(flexiTimer, SIGNAL(timeout()), FB_thread, SLOT(checkFlexiCommPort()));
connect(flexiTimer, SIGNAL(timeout()), FB_thread, SLOT(flexiTimerSignal()));
connect(FB_thread, SIGNAL(setCounterToZero()), this, SLOT(startReceiverTimer()));
connect(this->updateCounterTimer, SIGNAL(timeout()), FB_thread, SLOT(updateCounter()));
connect(flexiTimer, SIGNAL(timeout()), this, SLOT(startUpRoutine()));
FBToFLTP->wait();
FB_thread->wait();
}

void startIntegrator::startReceiverTimer()
{
qDebug() << "startReceiverTimer()";
updateCounterTimer = new QTimer();
updateCounterTimer->start(0);
}

void startIntegrator::startUpRoutine()
{
FB_thread->checkFlexiCommPort();
}

And the Flex_thread is:


Flex_thread::Flex_thread(QObject *parent) :
QThread(parent)
{
flexiCommPortNumber = "/dev/ttyUSB0";
// some code...
connect(this, SIGNAL(setCounterToZero()), this, SLOT(checkSignal()));
}

void Flex_thread::run()
{
do
{
receiveMsg();
}while(!stopped);
}

void Flex_thread::checkSignal()
{
qDebug() << "Signal ok!!"; // Just for checking that this is used
}

void Flex_thread::receiveMsg()
{
int numBytes = CommPort->bytesAvailable(); // Check if the data is there
if(numBytes > 0)
{
emit this->setCounterToZero(); // When something comes to this part of the program, I want to reset counterBytes after 1 sec.
// I have tried to initiate and start a counter here also
if (numBytes > 20) numBytes = 20;
char buff[20];
CommPort->readData(buff, numBytes); // Read bytes from CommPort

counterBytes = counterBytes + numBytes;

// ... Here I take care of the incomming data
}
}
void Flex_thread::updateCounter()
{
counterBytes = 0;
}
void Flex_thread::checkFlexiCommPort()
{
// do something
}

Can someone help me with these timers?

Lesiok
3rd February 2012, 13:09
You can start timer in any thread but in Flex_thread it will be not working because You don't start event loop in method Flex_thread::run.
Look at the source of QThread::run.

inger
6th February 2012, 13:04
I want to start a QTimer::singleShot in line 28 in FlexThread.
I do not manage to start it. I have tried to put in following line:
QTimer::singleShot(1000, this, SLOT(updateCounter()));

while updateCounter() set the counterBytes to 0.

I have also put exec() between line 14 and 15 in Flex_thread. But I think the timer will not start. The updateCounter() will not start.

How may I do this?

wysota
6th February 2012, 13:31
I have also put exec() between line 14 and 15 in Flex_thread.
Please think for a short while when this line is going to be executed.

inger
6th February 2012, 14:57
Oh sorry,
that will never be executed.:(

Are you able to help me how to get the QTimer started?

wysota
6th February 2012, 15:56
Read this: Keeping the GUI Responsive

sonia45
2nd November 2012, 13:37
I want to start a QTimer::singleShot in line 28 in FlexThread.
I do not manage to start it. I have tried to put in following line:
QTimer::singleShot(1000, this, SLOT(updateCounter()));

while updateCounter() set the counterBytes to 0.

I have also put exec() between line 14 and 15 in Flex_thread. But I think the timer will not start. The updateCounter() will not start.

How may I do this?


Thanks for the post... I really like the answer..