17

我目前有一个方法如下

void SomeMethod(int a)
{

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

     //After one sec
     SomeOtherFunction(a);
}

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

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

4

4 回答 4

54

实际上,您的问题有一个更优雅的解决方案,不需要成员变量或队列。使用 Qt 5.4 和 C++11,您可以直接从QTimer::singleShot(..)方法运行 Lambda 表达式!如果您使用的是 Qt 5.0 - 5.3,您可以使用 connect 方法将 QTimer 的超时信号连接到 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);
}
于 2013-08-14T18:11:11.307 回答
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(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 对象。此处包含它以尝试使示例代码接近问题。

于 2013-08-14T16:02:16.430 回答
1

If you are calling SomeMethod multiple times per second and the delay is always constant, you could put the parameter a to a QQueue and create a single shot timer for calling SomeOtherFunction, which gets the parameter from the 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
}
于 2013-08-14T16:42:03.620 回答
0

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

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

于 2013-08-14T19:52:56.410 回答