web-dev-qa-db-ja.com

Qtimerを使用して1秒の遅延を追加する方法

私は現在次のような方法を持っています

void SomeMethod(int a)
{

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

     //After one sec
     SomeOtherFunction(a);
}

このメソッドは、実際には信号に接続されているスロットです。 Qtimerを使用して1秒の遅延を追加したいのですが、これを達成する方法がわかりません。タイマーは終了時に信号をトリガーするため、その信号はパラメーターを受け取らない別のメソッドにアタッチする必要があります。このタスクを達成する方法についての提案はありますか?

pdate:信号は1秒間に複数回呼び出され、遅延は1秒間です。ここでの問題は、タイマーのtimeout()シグナルに接続されたスロットにパラメーターを渡すことです。私の最後のアプローチは、クラスのメンバー変数に値を格納し、変数が使用されている間に変更されないようにmutexを使用することです。ただし、ここでより簡単なメソッドを探しています。

15
Rajeshwar

私はあなたの質問の言い方に少し混乱していますが、タイマーの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オブジェクトを使用する必要はありません。これは、サンプルコードを質問に近づけようとするためにここに含まれています。

1
TheDarkKnight

実際、メンバー変数やキューを必要としない質問には、はるかに多くのエレガントなソリューションがあります。 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);
}
50
Linville

SomeMethodを1秒間に複数回呼び出しており、遅延がalways定数である場合、パラメーター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
}
1
user362638

QTimer::startがブロックしていないため、これは機能しません。

タイマーはQTimer::singleShotで開始し、QTimerがタイムアウトした後に実行されるスロットに接続する必要があります。

0
segfault