[英]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.