2009-11-09

QTimer in QThread

Multithreaded programming is also a useful paradigm for performing time-consuming operations without freezing the user interface of an application. QThread is the easy-to-use class in Qt allow user to implement things in a sperated thread.

"As of Qt4, you can use QThread to start your own event loops. This might sound somewhat uninteresting at first, but it means you can have your own signals and slots outside the main thread."

In GUI applications, the main thread is also called the GUI thread because it's the only thread that is allowed to perform GUI-related operations. You can implement, for instance, of a algorithm executed in a blocking way, into a sperated thread. Therefore, your GUI will not be frozen during the execution of algorithm. Then connect the main thread and algorithm thread by signal and slots. Namely, you can now emit a signal in one thread and receive it in a slot in a different thread.

The following is a simple example, in which a second-timer is wrapped in a QThread and a QWidget in main thread can start and stop the timer in any time.

//-----------------------------
CookingClock.cpp in timer thread
//-----------------------------


CookingClock::CookingClock(QObject *parent )
:QThread( parent)
,iSeconds_(10)
,iSecondsAccu_(0)
{

timer_.setInterval(1000); //second timer
connect( &timer_, SIGNAL(timeout()), this, SLOT(countSeconds()));

QThread::start();
}
void CookingClock::run()
{
exec();
}
void CookingClock::countSeconds()
{
iSecondsAccu_++;
emit( secondTicked(iSeconds_ - iSecondsAccu_));

if(iSecondsAccu_>=iSeconds_)
{
emit( timeIsUp());
timer_.stop();
}
}
void CookingClock::stop()
{
if(timer_.isActive())
{
timer_.stop();
}
}
void CookingClock::start()
{
iSecondsAccu_ = 0;
timer_.start();
}



//-----------------------------
CookingClockWidget.cpp in main thread
//-----------------------------



CookingClockWidget::CookingClockWidget(QWidget *parent)
:QWidget(parent)
, clock_(0)
{
clock_ = new CookingClock_v2();
QPushButton* pButtonStart = new QPushButton("start");
QPushButton* pButtonStop = new QPushButton("stop");
connect( pButtonStart, SIGNAL(clicked()), clock_, SLOT(start()));
connect( pButtonStop, SIGNAL(clicked()), clock_, SLOT(stop()));
connect( clock_, SIGNAL(secondTicked(int)), this, SLOT(print(int)));
QHBoxLayout* pLayout = new QHBoxLayout;
pLayout->addWidget(pButtonStart);
pLayout->addWidget(pButtonStop);

setLayout(pLayout);
}
void CookingClockWidget::print( int second)
{
qDebug("second : %d", second);
}




Reference:

No comments:

Post a Comment