我在qt中实现了状态模式。
在我的EnterIdleState函数中,我正在连接一个单一计时器来启动它。在第一次调用时,这可以正常工作,但是在第二次尝试时,计时器不会触发,尽管连接是像以前一样进行的:
Codeflow是这样的:
SetNewState(newIdleState());
IdleState::doWork();
SetNewState(new WorkState());
WorkdState::doWork();
SetNewState(newIdleState());
SetNewState如下所示:
void IridiumProcessor::SetNewState(State* pNewState)
{
if (m_pCurrentState)
{
m_pCurrentState->LeaveState();
delete m_pCurrentState;
}
m_pCurrentState = pNewState;
if (m_pCurrentState)
m_pCurrentState->EnterState();
}
在输入IdleState时,我连接了单次计时器:
void IdleState::EnterState()
{
QTimer::singleShot(1000,this,SLOT(OnTimeout()));
}
void IdleState::OnTimeout()
{
qDebug() << "IdleState OnTimeout";
}
当我使用QTimer membervar而不是静态singleShot调用时,会发生同样的事情。
答案 0 :(得分:1)
我发现只有几个可能的原因发生,除了真正的核心错误,如内存损坏等。
可能是在超时到期之前调用您的EnterState()方法。第二个呼叫取消前一个呼叫,它一次又一次地重复。为了调试它,你应该向EnterState()方法添加一个调试输出,最好是随时间,以查看它是否真的发生。如果没有,那就意味着我错了。
也可能是你在发出信号之前摧毁接收器,就像chalup建议的那样。
另一种可能性是你通过一些冗长的操作来阻止事件线程。在控件返回到计时器所在的线程的Qt事件循环之前,计时器不会触发。对于单线程应用程序,它是主事件循环。
答案 1 :(得分:0)
我将日志添加到IdleState析构函数:也许你在QTimer超时之前在IridiumProcessor :: SetNewState中销毁它们?
另请考虑使用QStateMachine而不是编写自己的解决方案。