繁体   English   中英

QTimer isActive返回true,但其余时间返回-1

[英]QTimer isActive returns true, but remainingTime returns -1

计时器是在开始时定义并启动的:

QTimer *teleTimer;
teleTimer = new QTimer();
QObject::connect(teleTimer, SIGNAL(timeout()), this, SLOT(somefunction1())); 
teleTimer->start(200);

然后在某处停止,并调用另一个函数somefunction2() 该功能完成后,计时器将再次启动:

if (teleTimer->isActive())
{
    qDebug() << teleTimer->remainingTime();
    teleTimer->stop();
    delete teleTimer;
}
teleTimer = new QTimer();
QObject::connect(teleTimer, SIGNAL(timeout()), this, SLOT(somefunction3())); 
teleTimer->start(200);

但是, teleTimer->isActive()返回true ,而teleTimer->remainingTime()返回-1 ,则应用程序崩溃了:

Thread 2 Crashed:: QThread
0   org.qt-project.QtCore           0x000000010ed4be3b QObject::killTimer(int) + 27
1   org.qt-project.QtCore           0x000000010ed5a9b9 QTimer::stop() + 25
2   com.yourcompany.QTGCS           0x000000010dffa609 TelemetrySerialWorker::setTelemetryMode(int) + 745 (telemetryserialworker.cpp:114)

那么如何解决呢? 谢谢。

更新:此问题已解决。 感谢所有的答复。 下次,我将尝试以一种良好的格式发布问题。 谢谢。

有了@eyllanesc的提示,我的问题终于解决了。

一开始,我使用delete teleTimer然后我的程序开始崩溃。 当时我以为原因是在再次调用此函数时,计时器并未真正停止。 然后,我更改了代码以运行另一个单发计时器,以便它确实有一个计时器要停止。

一开始:(崩溃)

void timerSwitch()
{
    if (teleTimer->isActive())
    {
        qDebug() << teleTimer->remainingTime();
        teleTimer->stop();
        delete teleTimer;
    }
    if (mode == 1)
    {
        teleTimer = new QTimer();
        QObject::connect(teleTimer, SIGNAL(timeout()), this, SLOT(somefunction())); 
        teleTimer->start(200);
    }
    else if (mode == 2)
    {
        somefunction2();
    }

}

第一次更改:(崩溃)

void timerSwitch()
{
    if (teleTimer->isActive())
    {
        qDebug() << teleTimer->remainingTime();
        teleTimer->stop();
        delete teleTimer;
    }
    if (mode == 1)
    {
        teleTimer = new QTimer();
        QObject::connect(teleTimer, SIGNAL(timeout()), this, SLOT(somefunction())); 
        teleTimer->start(200);
    }
    else if (mode == 2)
    {
        teleTimer = new QTimer();
        teleTimer.singleshot(..., ..., SLOT(somefunction2()));
    }

}

然后,在@eyllanesc提供的提示下,我将代码更改为:

void timerSwitch()
{
    if (teleTimer->isActive())
    {
        qDebug() << teleTimer->remainingTime();
        teleTimer->stop();
        teleTimer->deleteLater();
    }
    if (mode == 1)
    {
        teleTimer = new QTimer();
        QObject::connect(teleTimer, SIGNAL(timeout()), this, SLOT(somefunction())); 
        teleTimer->start(200);
    }
    else if (mode == 2)
    {
        teleTimer = new QTimer();
        teleTimer.singleshot(..., ..., SLOT(somefunction2()));
    }

}

我的程序仍然崩溃。

然后,我将代码更改为:

void timerSwitch()
{
    if (teleTimer->isActive())
    {
        qDebug() << teleTimer->remainingTime();
        teleTimer->stop();
        teleTimer->deleteLater();
    }
    if (mode == 1)
    {
        teleTimer = new QTimer();
        QObject::connect(teleTimer, SIGNAL(timeout()), this, SLOT(somefunction())); 
        teleTimer->start(200);
    }
    else if (mode == 2)
    {
        somefunction2();
    }

}

这次我的程序运行正常。 我测试了20次以上,都正常工作并且没有崩溃。

在此过程中,我的计算机给出的所有原因都与此类似:

Thread 2 Crashed:: QThread
0   org.qt-project.QtCore           0x000000010ed4be3b QObject::killTimer(int) + 27
1   org.qt-project.QtCore           0x000000010ed5a9b9 QTimer::stop() + 25
2   com.yourcompany.QTGCS           0x000000010dffa609 TelemetrySerialWorker::setTelemetryMode(int) + 745 (telemetryserialworker.cpp:114)

我以为错误是从stop() ,因为isActive()返回true ,而remainingTime() isActive() remainingTime()返回-1 我的理解是,何时调用isActive()时,确实确实没有停止计时器,但是当调用remainingTime()时,计时器已停止。 然后我觉得这不应该那么愚蠢。 我仍然有疑问,但是我的问题解决了。 有空的时候我会更新更多的细节。 谢谢所有的同胞回答我。

一般来说,如果要在序列中调用函数,则最简单的方法是将序列保留在表中,并使用单次计时器。 重新创建计时器或连接很昂贵。

#include <QtCore>
#include <functional>
#include <initializer_list>

class Sequencer : public QObject {
public:
  using base_class = QObject;
  struct Element {
    int delay = 0;
    std::function<void()> functor;
  };
  explicit Sequencer(QObject *parent = {}) : QObject(parent) {}
  // takes care of initializer list and other compatible initializers
  Sequencer(QVector<Element> init, QObject *parent = {}) : 
    QObject(parent), m_sequence(std::move(init)) {}
  void start(int index = 0) {
    m_it = m_sequence.begin() + index;
    m_timer.start(m_it->delay, this);
  }
  int stop() {
    m_timer.stop();
    return m_it - m_sequence.begin();
  }
protected:
  void timerEvent(QTimerEvent *event) override {
    if (m_timer.timerId() != event->timerId())
      return base_class::timerEvent(event);
    m_it->functor();
    m_it++;
    if (m_it != m_sequence.end())
      m_timer.start(m_it->delay, this);
    else
      m_timer.stop();
  }
private:
  QVector<Element> m_sequence;
  QVector<Element>::const_iterator m_it = m_sequence.begin();     
  QBasicTimer m_timer;
};

您可以像这样使用它,例如:

class MyClass { // can be QObject, but doesn't have to be
  Sequence m_seq{
    {200, [=]{ function1(); }},   // after 200ms delay
    {0,   [=]{ function2(); }},   // after no delay
    {500, [=]{ function3(); }},   // after 500ms delay
    {0,   [=]{ loop(); }}};       // and right away loop the sequence
  void function1();
  void function2();
  void function3();
  void loop() { m_seq.start(); }
public:
  MyClass() {
    m_seq.start();
  }
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM