如何使用Qtimer添加1秒延迟

how to add a 1 second delay using Qtimer

本文关键字:1秒 延迟 添加 Qtimer 何使用      更新时间:2023-10-16

我目前有一个方法,如下

void SomeMethod(int a)
{
     //Delay for one sec.
     timer->start(1000);
     //After one sec
     SomeOtherFunction(a);
}

这种方法实际上是一个附加到信号上的插槽。我想使用Qtimer添加一秒的延迟。但是我不确定如何实现这一点。由于定时器在完成时触发信号,并且该信号将需要附加到另一个不接受任何参数的方法。关于我如何完成这项任务,有什么建议吗。?

更新:信号将在一秒钟内被调用多次,延迟将持续一秒钟。我在这里的问题是将一个参数传递到附加到计时器的timeout()信号的插槽。我的最后一种方法是将值存储在类的memeber变量中,然后使用互斥锁来保护它在使用变量时不被更改。然而,我在这里寻找更简单的方法。

实际上,对于您的问题,有一个更为优雅的解决方案,它不需要成员变量或队列。使用Qt 5.4和C++11,您可以直接从QTimer::singleShot(..)方法运行Lambda表达式!如果使用Qt 5.0-5.3,则可以使用connect方法将QTimer的超时信号连接到Lambda表达式,Lambda表达式将调用需要使用适当参数延迟的方法。

编辑:Qt 5.4版本只需要一行代码!

Qt 5.4(及更高版本)

void MyClass::SomeMethod(int a) {
  QTimer::singleShot(1000, []() { SomeOtherFunction(a); } );
}

Qt 5.0-5.3

void MyClass::SomeMethod(int a) {
  QTimer *timer = new QTimer(this);
  timer->setSingleShot(true);
  connect(timer, &QTimer::timeout, [=]() {
    SomeOtherFunction(a);
    timer->deleteLater();
  } );
  timer->start(1000);
}

我对你表达问题的方式有点困惑,但如果你问如何获得定时器的timeout()信号来调用带有参数的函数,那么你可以创建一个单独的槽来接收超时,然后调用你想要的函数。类似这样的东西:-

class MyClass : public QObject
{
    Q_OBJECT
public:
    MyClass(QObject *parent);
public slots:
    void TimerHandlerFunction();
    void SomeMethod(int a);
private:
    int m_a;
    QTimer m_timer;
};

实施:-

MyClass::MyClass(QObject *parent) : QObject(parent)
{
    // Connect the timer's timeout to our TimerHandlerFunction()
    connect(&m_timer, SIGNAL(timeout()), this, SLOT(TimerHandlerFunction()));
}
void MyClass::SomeMethod(int a)
{
    m_a = a; // Store the value to pass later
    m_timer.setSingleShot(true); // If you only want it to fire once
    m_timer.start(1000);
}
void MyClass::TimerHandlerFunction()
{
    SomeOtherFunction(m_a);
}

请注意,QObject类实际上有一个计时器,您可以通过调用startTimer()来使用它,因此您实际上不需要在这里使用单独的QTimer对象。这里包含它是为了尽量让示例代码接近问题。

如果每秒调用SomeMethod多次,并且延迟总是常量,则可以将参数a设置为QQueue,并创建一个用于调用SomeOtherFunction的单次计时器,该计时器从QQueue获取参数。

void SomeClass::SomeMethod(int a)
{
    queue.enqueue(a);
    QTimer::singleShot(1000, this, SLOT(SomeOtherFunction()));
}
void SomeClass::SomeOtherFunction()
{
    int a = queue.dequeue();
    // do something with a
}

这不起作用,因为QTimer::start没有阻塞。

您应该用QTimer::singleShot启动计时器,并将其连接到一个插槽,该插槽将在QTimer超时后执行。