Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ QTimer isActive返回true,但remainingTime返回-1_C++_Qt_Qtimer - Fatal编程技术网

C++ QTimer isActive返回true,但remainingTime返回-1

C++ QTimer isActive返回true,但remainingTime返回-1,c++,qt,qtimer,C++,Qt,Qtimer,在开始时定义并启动计时器: QTimer *teleTimer; teleTimer = new QTimer(); QObject::connect(teleTimer, SIGNAL(timeout()), this, SLOT(somefunction1())); teleTimer->start(200); 然后它在某个地方停止,并调用另一个函数somefunction2。该功能完成后,计时器再次启动: if (teleTimer->isActive()) { q

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

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);
那么如何解决这个问题呢?谢谢


更新:这个问题已经解决了。谢谢你的回复。下次我会试着用一个好的格式发布一个问题。谢谢。

在@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();
    }

}

我以为错误是从stop出来的,因为isActive返回true,但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;
};

将delete teleTimer更改为delete teleTimer->delete Later@你是说改成teleTimer->deleteLater?我试过了,但还是失败了。我认为问题来自teleTimer->stop而非delete。@eyllanesc您可能是对的。。。让我做更多的测试。这可能是一个竞争条件,因为根据堆栈跟踪涉及多个线程。你能创建一个复制崩溃的模型吗?啊,现在更有意义了。但是,您仍然不需要删除和重新创建,只需断开连接并连接到新插槽即可。我之所以提到这一点,是因为有时在删除过程中,计时器回调正在运行,这会导致这些问题。Disc/conn不会导致地毯从机下回调中拉出。不过,你已经解决了这个问题,所以不必继续了,我只是想提一下我的理由。谢谢你的回复。我以前从未用过你提到的方法。我觉得很有趣,我会试试看。所有函数都被多次调用,例如,最初每隔200ms调用一次somefunction1,然后如果GUI没有交互,它将无限期地每隔200ms调用一次此函数。然后,如果单击某个按钮,它将转到某个功能2或其他功能。
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()));
    }

}
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();
    }

}
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)
#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();
  }
};