QTimer isActive returns true,但 remainingTime returns -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()
returnstrue
,而teleTimer->remainingTime()
returns-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)
那么如何解决这个问题呢?谢谢。
更新:此问题已解决。感谢所有的答复。下次我会尝试 post 一个好的格式的问题。谢谢。
在@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()
returns true
,但是 remainingTime()
returns -1
.我的理解是在调用isActive()
的时候,定时器确实没有停止,但是在调用remainingTime()
的时候,定时器停止了。然后我觉得这不应该这么愚蠢。我仍然有疑问,但我的问题已经解决了。当我有时间时,我会更新更多细节。谢谢各位大侠回复我
一般来说,如果您按顺序调用函数,最简单的方法是将顺序保持在 table 中,并使用单次定时器。重新创建计时器或连接很昂贵。
#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();
}
};
开始时定义并启动了一个定时器:
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()
returnstrue
,而teleTimer->remainingTime()
returns-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)
那么如何解决这个问题呢?谢谢。
更新:此问题已解决。感谢所有的答复。下次我会尝试 post 一个好的格式的问题。谢谢。
在@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()
returns true
,但是 remainingTime()
returns -1
.我的理解是在调用isActive()
的时候,定时器确实没有停止,但是在调用remainingTime()
的时候,定时器停止了。然后我觉得这不应该这么愚蠢。我仍然有疑问,但我的问题已经解决了。当我有时间时,我会更新更多细节。谢谢各位大侠回复我
一般来说,如果您按顺序调用函数,最简单的方法是将顺序保持在 table 中,并使用单次定时器。重新创建计时器或连接很昂贵。
#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();
}
};