Qt如何杀死一个定时器开始使用startTimer() API

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

本文关键字:开始 startTimer API 定时器 一个 Qt 何杀死      更新时间:2023-10-16

我使用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("nnnnn WARM UP TIMER RUNNING nnnnn");
         killTimer(warmUpTimerID);
     }
}

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

timerEvent接收所有定时器的事件。为了区别它们,QTimerEvent类有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("nnnnn WARM UP TIMER RUNNING nnnnn");
        killTimer(warmUpTimerID);
    }
}

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

  1. 您需要确保特定的timerEvent调用与您的计时器相关。

  2. QBasicTimer是一个很好的方便的定时器id包装,您可以使用它来代替原始id。

  3. 类成员中的静态变量可以被潜在地重用,这是令人讨厌的bug的来源。

  4. isWarmupStarted是多余的,它的值与m_warmupRemaining > 0相同。

  5. 通过显式地使用16位无符号整数作为剩余时间计数器,您不会节省任何东西。

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