4

Qt を使用してプログラムに取り組んでおり、コードの一部は Windows サンプルに基づいています。私が抱えている問題と、私がよく理解していないことは、同じコードがどのように Qt GUI をブロックするかということですが、Windows アプリではまったく問題なく動作します。

例を次に示します。カメラからデータを取得し、処理を行ってから画面に表示するプログラムがあります。Windows のサンプルには、次のようなものがあります。

// Create an event with these self-explanatory parameters
// This event signals when the next frame is ready to process
HANDLE frameEvent  = CreateEvent(nullptr, TRUE, FALSE, nullptr)

// Now run a while loop which magically doesn't block
HANDLE hEvents[1];

while (WM_QUIT != msg.message)
{
  hEvents[0] = frameEvent;

  DWORD dwEvent = MsgWaitForMultipleObjects(1, hEvents, FALSE, INFINITE, QS_ALLINPUT);

  // If we have our event run some processing
  if (WAIT_OBJECT_0 == dwEvent)
  {
    update();
  }
  // Else handle input or whatever
}

更新関数は次のようになります。

if (WAIT_OBJECT_0 = WaitForSingleObject(frameEvent, 0)
{
  getTheFrame();
  processTheFrame();
  drawTheFrame();
}

Qtで同じように実装しようとすると、すべてがフリーズし、whileループが永久に実行されます。私が得た解決策は、別のスレッド (QThread) でループを実行し、次のように新しいフレームの準備ができたときに信号を発することです。

void Worker::run()
{
    running_ = true;

    while (running_)
    {
        if (WaitForSingleObject(frameEvent, 0) == WAIT_OBJECT_0)
        {
            emit signalFrame();
        }

        // This is necessary or it will still freeze!
        usleep(15);
    }
}

次に、信号はUpdate()、Windows サンプルのメソッドと同様のジョブを実行するスロットに接続されます。

これで問題なく動作しますが、次のフレームが利用可能になる前に 1 つのフレームを処理できる場合に限られます。

私の処理がより複雑になり、カメラのフレームレートよりも遅くなったため、プログラムは応答を停止しました。Windows サンプルのまったく同じコードは引き続き正常に動作し、フレームレートは低下しますが、すべてが描画され、GUI の応答性は維持されます。

誰かが何が起こっているのかを説明できますか?また、可能な解決策は何ですか?

4

1 に答える 1

3

Win32 バージョンはMsgWaitForMultipleObjects. その名前が示すように、指定されたオブジェクトが通知される、ウィンドウ メッセージ (および で呼び出されるためQS_ALLINPUT任意のウィンドウ メッセージ) のいずれかを待ちます。おそらく、コードは後でウィンドウ メッセージもディスパッチします。

あなたのバージョンは を呼び出しますWaitForSingleObject。その名前が示すように、指定されたオブジェクトのみを待機します。ウィンドウメッセージでブロックを解除しません。

于 2013-04-20T06:35:10.380 に答える