Qt 如何终止使用 startTimer() API 启动的计时器?

Qt How to kill a timer started using startTimer() API?

我使用 timerEvent(QTimerEvent *e) 更新倒数计时器,完成后我调用 killTimer(timerID)timerEvent() 仍在调用。 那么正确的杀灭方法是什么?

代码:

void MainWindow::timerEvent(QTimerEvent *e)
{
    Q_UNUSED(e);

    static uint16_t u16RemTime = MAX_WARMUP_TIME_IN_SECS;
     if((true == isWarmUpStarted) && (u16RemTime > 0))
     {

         u16RemTime--;
         objptrSplashScreen->SetTime(u16RemTime);
     }
     else
     {
         //Still running
         qWarning("\n\n\n\n\n WARM UP TIMER RUNNING \n\n\n\n\n");
         killTimer(warmUpTimerID);
     }
}

如果有帮助的话。我在同一个 GUI 线程中的两个不同 类 中有两个这样的计时器 运行。我将如何杀死它?

如果您使用 QTimerQBasicTimer,您可以在其中之一上调用 stop()。

timerEvent 接收所有定时器的事件。为了区分它们 QTimerEvent class 有 int timerId() const 方法。所以你的活动应该是这样的:

void MainWindow::timerEvent(QTimerEvent *e)
{
    if (e->timerId() != warmUpTimerID)
        return;

    static uint16_t u16RemTime = MAX_WARMUP_TIME_IN_SECS;
    if((true == isWarmUpStarted) && (u16RemTime > 0))
    {
        u16RemTime--;
        objptrSplashScreen->SetTime(u16RemTime);
    }
    else
    {
        //Still running
        qWarning("\n\n\n\n\n WARM UP TIMER RUNNING \n\n\n\n\n");
        killTimer(warmUpTimerID);
    }
}
  1. 您需要确保特定的 timerEvent 调用与您的计时器相关。

  2. QBasicTimer 是一个非常方便的计时器 id 包装器,您可以使用它代替原始 id。

  3. 类 成员中可能会被重用的静态变量是严重错误的来源。

  4. isWarmupStarted是多余的,它的值等同于m_warmupRemaining > 0.

  5. 您并没有为剩余时间计数器显式使用 16 位无符号整数来保存任何内容。只需使用一个 int.

  6. 在变量名中明确提及类型的风格是,如果你的雇主不强迫你使用它,就不要使用它。跟踪这些事情是编译器的工作,而不是你的,如果你不这样做,事情有时会变得毛茸茸的不是 C 和 winapi。

因此:

class MainWindow : public QMainWindow {
  Q_OBJECT
  QSplashScreen * m_splashScreen;
  QBasicTimer m_warmupTimer;
  int m_warmupRemaining;
  void timerEvent(QTimerEvent * ev) {
    if (ev->timerId() != m_warmupTimer.timerId()) return;
      // No need to call the empty QMainWindow::timerEvent(ev).
      // All timerEvent implementations in public Qt classes are empty,
      // to make your life easier.

    if (m_warmupRemaining > 0) {
      m_warmupRemaining --;
      m_splashScreen->SetTime(m_warmupRemaining);
    } else {
       m_warmupTimer.stop();
    }
  }
};