如何使用Qtimer添加1秒延迟

时间:2013-08-14 15:51:20

标签: c++ qt qtimer

我目前有一个方法如下

void SomeMethod(int a)
{

     //Delay for one sec.
     timer->start(1000);

     //After one sec
     SomeOtherFunction(a);
}

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

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

4 个答案:

答案 0 :(得分:49)

实际上,您的问题还有更多优雅的解决方案,不需要成员变量或队列。使用Qt 5.4和C ++ 11,您可以run a Lambda expression right from the QTimer::singleShot(..) method!如果您使用的是Qt 5.0 - 5.3,则可以使用连接方法connect the QTimer's timeout signal to a Lambda expression来调用需要使用适当参数延迟的方法。

编辑:在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);
}

答案 1 :(得分:1)

我对你的问题的表达方式感到有点困惑,但如果你问如何让定时器的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(timout()), 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对象。这里包含它是为了使示例代码保持接近问题。

答案 2 :(得分:1)

如果您每秒多次调用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
}

答案 3 :(得分:0)

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

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