私は現在次のような方法を持っています
void SomeMethod(int a)
{
//Delay for one sec.
timer->start(1000);
//After one sec
SomeOtherFunction(a);
}
このメソッドは、実際には信号に接続されているスロットです。 Qtimerを使用して1秒の遅延を追加したいのですが、これを達成する方法がわかりません。タイマーは終了時に信号をトリガーするため、その信号はパラメーターを受け取らない別のメソッドにアタッチする必要があります。このタスクを達成する方法についての提案はありますか?
pdate:信号は1秒間に複数回呼び出され、遅延は1秒間です。ここでの問題は、タイマーのtimeout()シグナルに接続されたスロットにパラメーターを渡すことです。私の最後のアプローチは、クラスのメンバー変数に値を格納し、変数が使用されている間に変更されないようにmutexを使用することです。ただし、ここでより簡単なメソッドを探しています。
私はあなたの質問の言い方に少し混乱していますが、タイマーの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(..)
メソッドから直接Lambda式を実行 ! Qt 5.0-5.3を使用している場合は、connectメソッドを使用して QTimerのタイムアウト信号をLambda式に接続する を使用し、適切なパラメーターで遅延する必要があるメソッドを呼び出します。
編集:Qt 5.4リリースでは、コードは1行だけです!
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
を1秒間に複数回呼び出しており、遅延がalways定数である場合、パラメーター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がタイムアウトした後に実行されるスロットに接続する必要があります。