c++ - QThread and QTimer -


i'm working on application developed qt 4.6.

i want create custom timer counts in separate thread. however, want timer able send signals main thread.

i subclassed qthread doesn't seem work.

here timer.h:

#ifndef timer_h #define timer_h  #include <qtcore/qobject> #include <qtcore/qthread> #include <qtcore/qtimer>  class timer : public qthread {     q_object public:     explicit timer(qobject *parent = 0);     ~timer();      // true if timer active     bool iscounting();      // start timer number of seconds     void startcounting(int value = 300);     void stopcounting();      // number of seconds reach     int maximum();      // current value of timer     int value();      // elapsed time since timer has started     int elapsedtime();  signals:     // sent when timer finishes count     void timeout();     // event emited @ each second when timer active     void top(int remainingseconds);  protected:     // launch thread     //virtual void run();  private slots:     // decrements remaining time @ each second , emits top()     void timerevent();  private:     qtimer* _timer;     // remaining time     int _left;     // number of seconds @ timer startup     int _maximum; };  #endif // timer_h 

and timer.cpp:

#include "timer.h"  timer::timer(qobject *parent) :     qthread(parent) {     _timer = new qtimer(this);     _maximum = 0;     _left = 0;     connect(_timer, signal(timeout()), this, slot(timerevent())); }  timer::~timer() {     delete _timer; }  bool timer::iscounting() {     // test if timer still active     return _timer->isactive(); }  void timer::startcounting(int value) {     qdebug() << qstring("start timer %1 secs").arg(qstring::number(value));     if(_left != 0 || _timer->isactive())     {          _timer->stop();     }      _maximum = value;     _left = value;      // emit first top     emit top(_left);      // start timer: 1000 msecs     _timer->start(1000);      // start thread     start(); }  void timer::stopcounting() {     qdebug() << qstring("stopping timer @ %1 secs => %2 secs remaining.").arg(qstring::number(elapsedtime()), qstring::number(_left));     // stop timer     _timer->stop();     _left = 0;     _maximum = 0;     // kill thread     terminate(); }  int timer::maximum() {     return _maximum; }  int timer::value() {     return _left; }  void timer::timerevent() {     qdebug() << "timer event";     if(--_left == 0)     {         // stop timer         _timer->stop();         // emit end of timer         emit timeout();         // stop thread         terminate();     }     else     {         // emit signal @ each second         emit top(_left);     } }  int timer::elapsedtime() {     return (_maximum - _left); } 

edit

i realized object tried move thread singleton. lead problem (see here).

you don't need subclass qthread in particular case. , in general, abstain subclassing qthread unless sure need.

here quick example how setup worker , timer in thread , launch it:

the worker class:

class worker : public qobject {     q_object public:     explicit worker(qobject *parent = 0) : qobject(parent) {}  signals:     void dosomething();  public slots:     void trigger() {         emit dosomething();     } }; 

main.cpp

int main(int argc, char *argv[]) {     qcoreapplication a(argc, argv);      mainthreadobject o;      qthread *thread = new qthread;     worker w;     qtimer timer;     timer.setinterval(1000);      timer.movetothread(thread);     w.movetothread(thread);      qobject::connect(thread, signal(started()), &timer, slot(start()));     qobject::connect(&w, signal(dosomething()), &o, slot(dosomething()));     qobject::connect(&timer, signal(timeout()), &w, slot(trigger()));      thread->start();      return a.exec(); } 

so, have mainthreadobject represents qobject derived living in main thread. create timer , worker object, used wrap signal , slot avoid need of subclassing qthread. timer setup , , worker moved new thread, thread started() signal connected timer start() slot, worker dosomething() signal connected main thread object dosomething() slot, , timer timeout() signal connected worker trigger() slot. thread started initiates entire chain in event loop.

as result, mainthreadobject::dosomething() called every second, signal emitted secondary thread.


Comments

Popular posts from this blog

monitor web browser programmatically in Android? -

Shrink a YouTube video to responsive width -

wpf - PdfWriter.GetInstance throws System.NullReferenceException -