Russian Qt Forum

Qt => Общие вопросы => Тема начата: Roman_L от Июль 31, 2017, 13:17



Название: bool QTimer::isActive() особенности работы
Отправлено: Roman_L от Июль 31, 2017, 13:17
Доброго времени суток!
Я столкнулся со следующей проблемой: вызов 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), но хочется меньше натыкаться на подобное...


Название: Re: bool QTimer::isActive() особенности работы
Отправлено: Roman_L от Июль 31, 2017, 13:32
всё так:
Код:
inline bool isActive() const { return id >= 0; }
Код:
652	int QTimer::remainingTime() const
653 {
654     if (id != INV_TIMER) {
655         return QAbstractEventDispatcher::instance()->remainingTime(id);
656     }
657
658     return -1;
659 }