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
how to add a 1 second delay using Qtimer
提问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 SomeMethod
multiple times per second and the delay is alwaysconstant, 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
.
如果SomeMethod
每秒调用多次并且延迟始终不变,则可以将参数放入a
aQQueue
并创建一个用于调用的单次定时器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::start
is not blocking.
这不起作用,因为QTimer::start
没有阻塞。
You should start the timer with QTimer::singleShot
and connect it to a slot which will get executed after the QTimer times out.
您应该启动计时器QTimer::singleShot
并将其连接到一个插槽,该插槽将在 QTimer 超时后执行。