C++ 如何使用 Qtimer 添加 1 秒延迟

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18236480/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:49:11  来源:igfitidea点击:

how to add a 1 second delay using Qtimer

c++qtqtimer

提问by Rajeshwar

I currently have a method which is as follows

我目前有一个方法如下

void SomeMethod(int a)
{

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

     //After one sec
     SomeOtherFunction(a);
}

This method is actually a slot that is attached to a signal. I would like to add a delay of one sec using Qtimer.However I am not sure on how to accomplish this. Since the timer triggers a signal when its finished and the signal would need to be attached to another method that does not take in any parameters. Any suggestion on how I could accomplish this task.?

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

Update :The signal will be called multiple times in a second and the delay will be for a second. My issue here is passing a parameter to the slot attached to timeout() signal of a timer. My last approach would be to store the value in a memeber variable of a class and then use a mutex to protect it from being changed while the variable is being used .however I am looking for simpler methods here.

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

采纳答案by TheDarkKnight

I'm a bit confused by the way you phrase your question, but if you're asking how to get the timer's timeout() signal to call a function with a parameter, then you can create a separate slot to receive the timeout and then call the function you want. Something like this: -

我对你表达问题的方式有点困惑,但如果你问如何让计时器的 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;
};

Implementation: -

执行: -

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

Note that the QObject class actually has a timer that you can use by calling startTimer(), so you don't actually need to use a separate QTimer object here. It is included here to try to keep the example code close to the question.

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

回答by Linville

Actually, there is a much more elegant solutionto your question that doesn't require member variables or queues. With Qt 5.4 and C++11 you can run a Lambda expression right from the QTimer::singleShot(..)method! If you are using Qt 5.0 - 5.3 you can use the connect method to connect the QTimer's timeout signal to a Lambda expressionthat will call the method that needs to be delayed with the appropriate parameter.

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

Edit:With the Qt 5.4 release it's just one line of code!

编辑:随着 Qt 5.4 的发布,它只是一行代码!

Qt 5.4 (and later)

Qt 5.4(及更高版本)

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

Qt 5.0 - 5.3

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

回答by TheDarkKnight

If you are calling SomeMethodmultiple times per second and the delay is alwaysconstant, you could put the parameter ato a QQueueand create a single shot timer for calling SomeOtherFunction, which gets the parameter from the QQueue.

如果SomeMethod每秒调用多次并且延迟始终不变,则可以将参数放入aaQQueue并创建一个用于调用的单次定时器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
}

回答by segfault

That doesn't work because QTimer::startis not blocking.

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

You should start the timer with QTimer::singleShotand connect it to a slot which will get executed after the QTimer times out.

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