-1

qt5とopencvを使用して、qtを使用してユーザーインターフェイスを提供し、opencvで画像処理部分を実行するアプリケーションを作成します.....

これまでのところ、私のデザインは次のとおりです。

  1. qtメインGUIスレッドを使用して、ビデオとボタンやチェックボックスなどの標準コントロールを表示しています
  2. 画像をキャプチャして処理するために、QObject から派生したワーカー クラスを作成し、それをスレッドに移動しました。
  3. ワーカー クラス (Worker::process) で実行される関数にはブロッキング while ループがあります。
    • ビデオまたはカメラからフレームをキャプチャします
    • それにいくつかの処理を行います
    • cv::Mat から QImage に変換します
    • QImageを表示するためにメインスレッドに信号を送信します
  4. また、ユーザー入力を受け取るために、メインスレッドからワーカースロットへの信号の送信を使用していました

私が直面した問題は、イベント ループが while ループをブロックしているため、メイン スレッドからのシグナルがワーカーによって取り出されないことでした。

多くの検索の後、メインスレッドからの信号をワーカースロットに接続するときに Qt::DirectConnection 引数を使用するソリューションを思いつきました。当時の問題を解決したものです。

ここで、ブロッキング while ループ内に qtimer または qbasictimer を追加する必要があります...そして、タイマー スロット (qtimer の場合) と保護された timerEvent ハンドラー (qbasictimer の場合) が呼び出されることはありません。私の予感は、ループのブロッキングが原因であるということです

フォーラムで多くの検索と読み取りを行った後、何らかの形で全体的な設計が間違っている可能性があるという結論に達しました..そして、アプリケーションに機能を追加し続けると、これらの問題が表示され続けます.

現在、次の 2 つのオプションがあります。

  1. 何らかの方法でスレッドの exec() 関数をブロッキング while ループ内で呼び出します。専門家への質問は次のとおりです。「worker QObject クラス内で thread::exec() メソッドを呼び出すにはどうすればよいですか。exec() を呼び出すには、worker を実行しているスレッドへの参照が必要です」(短期的な解決策)

  2. 実装全体を変更します.....そしてここでの質問は次のとおりです:「私のオプションは何ですか.....」(長期)

私の言い回しや英語が何らかの形で問題を不明確にした場合は、お気軽に詳細をお尋ねください.....ありがとう...

4

1 に答える 1

2

ワーカーのブロッキング ループ内で、qApp->processEvents();定期的に呼び出します。

http://qt-project.org/doc/qt-5.1/qtcore/qcoreapplication.html#processEvents

#include <QApplication>
// ...
void Worker::doWork()
{
    while(true)
    {
        someLongImageProcessingFunction();
        qApp->processEvents();
    }
}

これにより、スロットが処理され、タイマーが更新されるようになります。

直接接続を使用すると、ワーカーにローカルな値にアクセスして変更できる場合がありますが、スレッド セーフに注意する必要があります。QMutexLockerGUI によって変更される値の前、およびワーカー スレッドが値を使用する直前に right を配置すると、うまくいくはずです。

http://qt-project.org/doc/qt-5.1/qtcore/qmutexlocker.html

また、これらのスロットのいずれかをワーカー スレッドで実行する場合は、QueuedConnection.

http://qt-project.org/doc/qt-5.1/qtcore/threads.html

http://qt-project.org/doc/qt-5.1/qtcore/qthread.html#details

Qt ドキュメントの一部では、QThread クラスのサブクラス化について説明しています。他の部分ではワーカー/プロデューサー モデルを推奨し、接続を使用してスレッドの使用方法を設定するだけです。通常、Worker/Producer モデルでは問題が少なくなります。

それが役立つことを願っています。

于 2013-09-13T23:05:43.783 に答える