定义一个计时器并在开始时启动:
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)
那么如何解决这个问题呢?感谢。
更新:此问题已解决。感谢所有的答复。我将尝试下次以良好的格式发布问题。感谢。
答案 0 :(得分:0)
通过@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()
会返回-1
。我的理解是,当调用isActive()
时,计时器确实没有以某种方式停止,但是当调用remainingTime()
时,计时器停止了。然后我觉得这不应该是那么愚蠢。我仍有疑问,但问题解决了。我有空的时候会更新更多细节。谢谢所有同伴回复我。
答案 1 :(得分:0)
一般来说,如果您按顺序调用函数,最简单的方法是将序列保存在表中,并使用单次定时器。重新创建计时器或连接是很昂贵的。
#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();
}
};