В настоящее время у меня есть метод, который заключается в следующем
void SomeMethod(int a)
{
//Delay for one sec.
timer->start(1000);
//After one sec
SomeOtherFunction(a);
}
Этот метод на самом деле является слотом, который присоединен к сигналу. Я хотел бы добавить задержку в одну секунду, используя Qtimer. Однако я не уверен, как это сделать. Так как таймер запускает сигнал, когда он закончен, и сигнал должен быть присоединен к другому методу, который не принимает никаких параметров. Любое предложение о том, как я мог бы выполнить эту задачу.
Обновить :
Сигнал будет вызываться несколько раз в секунду, а задержка будет на секунду. Моя проблема здесь заключается в передаче параметра в слот, связанный с сигналом таймера timeout ().
Мой последний подход состоял бы в том, чтобы сохранить значение в переменной memeber класса, а затем использовать мьютекс, чтобы защитить его от изменения во время использования переменной. Однако здесь я ищу более простые методы.
Меня немного смущает то, как вы формулируете свой вопрос, но если вы спрашиваете, как получить сигнал 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. Он включен здесь, чтобы попытаться сохранить пример кода близким к вопросу.
На самом деле, есть гораздо больше элегантное решение на ваш вопрос, который не требует членских переменных или очередей. С Qt 5.4 и C ++ 11 вы можете запустить лямбда-выражение прямо из QTimer::singleShot(..)
метод! Если вы используете Qt 5.0 — 5.3, вы можете использовать метод connect для соединить сигнал тайм-аута QTimer с лямбда-выражением это вызовет метод, который должен быть задержан с соответствующим параметром.
Редактировать: С выпуском 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);
}
Если вы звоните 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
}
Это не работает, потому что QTimer::start
не блокирует
Вы должны запустить таймер с QTimer::singleShot
и подключите его к слоту, который будет выполнен после истечения времени ожидания QTimer.