【问题标题】:Qt QTimer is it safe to stop it this way?Qt QTimer 以这种方式停止它是否安全?
【发布时间】:2012-08-16 07:08:48
【问题描述】:

在它的“超时”信号/槽函数中停止 Qt 的计时器是否安全? 在 Qt 文档中似乎找不到任何关于 QTimer 的信息。

我创建了一个计时器,它定期向服务器发送“保持活动”消息。 如果在发送我的消息时出现某种错误,我希望停止此计时器。

private:
   QTimer* mpKeepAliveTimer;

定时器是这样初始化的:

mpKeepAliveTimer = new QTimer(/* this */);

QObject::connect(mpKeepAliveTimer, SIGNAL(timeout()), this, SLOT(OnKeepAlive()));

mpKeepAliveTimer->start(KEEP_ALIVE_PERIOD);

就这样停止了:

if (mpKeepAliveTimer != NULL) // <-- Edited
{
    if (mpKeepAliveTimer->isActive() == true)
        mpKeepAliveTimer->stop();

    delete mpKeepAliveTimer;
    mpKeepAliveTimer = NULL;
}

超时函数如下所示:

void Classname::OnKeepAlive()
{
   if (isErrorFound == true)
      mpKeepAliveTimer->stop();   // <---- IS THIS SAFE?
}

谢谢。

【问题讨论】:

  • 第三个代码块可以使用精炼。没有必要在定时器被销毁之前停止它。整个区块可以缩减为delete mpKeepAliveTimer; mpKeepAliveTimer = NULL;

标签: c++ qt timer


【解决方案1】:

只要您没有明确使用排队连接,这是安全的。
这是因为 emit timeout() 函数在它连接到的所有插槽都被处理完之后才会返回。

但是,如果您使用的是队列连接,理论上可能会发生事件队列中仍有未处理的超时事件,因此为了使其超安全,您可以使用以下内容:

void Classname::OnKeepAlive()
{
    if (!mpKeepAliveTimer || !mpKeepAliveTimer->isActive()) return;

    if (isErrorFound)
    {
        mpKeepAliveTimer->stop();
    }
}

请注意,停止函数中的条件应为!= NULL 而不是== NULL。但是,您也可以按如下方式编写该函数:

if (mpKeepAliveTimer)
{
    delete mpKeepAliveTimer;
    mpKeepAliveTimer = NULL;
}

正如 cmets 中已经建议的那样,QTimer 将在其析构函数中自行停止。

【讨论】:

  • Uff.. 感谢您注意到“== NULL”的事情! (我在帖子中对此进行了编辑)我已经按照 Slavik81 的建议修改了计时器的停止过程(我不确定通过销毁我的计时器对象,它的析构函数是否会安全地停止超时过程......)谢谢 Tim,谢谢 Slavik81
猜你喜欢
  • 1970-01-01
  • 2021-03-05
  • 2021-02-21
  • 1970-01-01
  • 1970-01-01
  • 2021-06-15
  • 2013-12-01
  • 2011-06-23
  • 1970-01-01
相关资源
最近更新 更多