Доброго времени суток!
Я столкнулся со следующей проблемой: вызов QTimer::isActive() возвращает значение, по всей видимости, вычисляемое в процессе обработки событий. В общем так или иначе, но код вида
do {
doSomething();
} while(timer.isActive());
не работает как того ожидается (окей, мной). Вот код:
#ifndef OBJ_H
#define OBJ_H
#include <QWidget>
#include <QCoreApplication>
#include <QTimer>
class Obj : public QWidget
{
Q_OBJECT
public:
explicit Obj(QWidget *parent = 0);
~Obj();
void test();
QTimer *t1, *t2, *t3;
signals:
public slots:
void t1_timeout();
void t2_timeout();
void t3_timeout();
};
#endif // OBJ_H
#include "obj.h"
#include <QThread>
#include <QDebug>
Obj::Obj(QWidget *parent) : QWidget(parent)
{
qDebug()<<"obj::obj timer::isActive() test:";
t1 = new QTimer();
t2 = new QTimer();
t3 = new QTimer();
t1->setSingleShot(false);
t2->setSingleShot(true);
t3->setSingleShot(true);
connect(t1, SIGNAL(timeout()), SLOT(t1_timeout()));
connect(t2, SIGNAL(timeout()), SLOT(t2_timeout()));
connect(t3, SIGNAL(timeout()), SLOT(t3_timeout()));
t1->start(200);
t2->start(900);
t3->start(1500);
}
Obj::~Obj() {
delete t1;
delete t2;
delete t3;
}
void Obj::test()
{
do {
qDebug()<<"t2rt ="<<t2->remainingTime()<<"t2isA ="<<t2->isActive();
qApp->thread()->msleep(200);
} while(t3->remainingTime() > 0);
qDebug()<<"obj::obj end test.";
}
void Obj::t1_timeout()
{
qDebug()<<"t2->isActive() ="<<t2->isActive()
<<", t2->remainingTime() ="<<t2->remainingTime();
}
void Obj::t2_timeout()
{
qDebug()<<"t2->isActive() ="<<t2->isActive()
<<", t2->remainingTime() ="<<t2->remainingTime()
<<"t2 is time out.";
}
void Obj::t3_timeout()
{
qDebug()<<"t2->isActive() ="<<t2->isActive()
<<", t2->remainingTime() ="<<t2->remainingTime()
<<"t3 is time out.";
t1->stop();
t2->stop();
t3->stop();
}
#include <QApplication>
#include "obj.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Obj o;
//o.test();
return a.exec();
}
выдаёт примерно следующее (всё как предполагается):
obj::obj timer::isActive() test:
t2->isActive() = true , t2->remainingTime() = 699
t2->isActive() = true , t2->remainingTime() = 501
t2->isActive() = true , t2->remainingTime() = 295
t2->isActive() = true , t2->remainingTime() = 95
t2->isActive() = false , t2->remainingTime() = -1 t2 is time out.
t2->isActive() = false , t2->remainingTime() = -1
t2->isActive() = false , t2->remainingTime() = -1
t2->isActive() = false , t2->remainingTime() = -1
t2->isActive() = false , t2->remainingTime() = -1 t3 is time out.
если раскомментировать строку //o.test();
выдача будет
obj::obj timer::isActive() test:
t2rt = 900 t2isA = true
t2rt = 699 t2isA = true
t2rt = 496 t2isA = true
t2rt = 292 t2isA = true
t2rt = 89 t2isA = true
t2rt = 0 t2isA = true
t2rt = 0 t2isA = true
t2rt = 0 t2isA = true
obj::obj end test.
t2->isActive() = true , t2->remainingTime() = 0
t2->isActive() = false , t2->remainingTime() = -1 t2 is time out.
t2->isActive() = false , t2->remainingTime() = -1 t3 is time out.
Если сменить предка с QWidget на QObject и QApplication на QCoreApplication работать при раскомментированной строке //o.test(); будет
obj::obj timer::isActive() test:
t2rt = 0 t2isA = true
obj::obj end test.
t2->isActive() = true , t2->remainingTime() = 696
t2->isActive() = true , t2->remainingTime() = 498
t2->isActive() = true , t2->remainingTime() = 291
t2->isActive() = true , t2->remainingTime() = 91
t2->isActive() = false , t2->remainingTime() = -1 t2 is time out.
t2->isActive() = false , t2->remainingTime() = -1
t2->isActive() = false , t2->remainingTime() = -1
t2->isActive() = false , t2->remainingTime() = -1
t2->isActive() = false , t2->remainingTime() = -1 t3 is time out.
Для себя, как видите, нашёл выход (QTimer::remainingTime() > 0), но хочется меньше натыкаться на подобное...