我目前有一个方法如下
void SomeMethod(int a)
{
//Delay for one sec.
timer->start(1000);
//After one sec
SomeOtherFunction(a);
}
此方法实际上是附加到信号的插槽。我想用Qtimer添加一秒的延迟。但是我不知道如何实现这一点。由于定时器在完成时触发信号,并且信号需要连接到另一个不接受任何参数的方法。关于如何完成这项任务的任何建议。
更新 信号将在一秒钟内被多次调用,延迟将持续一秒钟。我的问题是将参数传递给附加到计时器的timeout()信号的插槽。 我的最后一种方法是将值存储在类的memeber变量中,然后使用互斥锁来保护它在使用变量时不被更改。但是我在这里寻找更简单的方法。
答案 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超时后执行的插槽。