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