2

ユーザーがカメラからビデオを見て記録できるプログラムを実行しています。QtMEL ライブラリを使用して、カメラ フィードと記録を取得しています。カメラが起動すると、QTconcurrent::run() で関数を呼び出してフレームを取得します。この関数内には、カメラ フィードがシャットダウンされたかどうかを確認する無限ループがあり、シャットダウンされた場合はループを終了します。このようなもの:

Q_FOREVER {
    frame = captureFrame();

    //Do stuff

    //check if we must finish grabbing
    if (isStopRequest() || isPauseRequest())
        break;
}

ユーザーがカメラを閉じて (フレームのグラブを停止し、スレッドを終了します)、プログラムが存在する場合は、すべて問題ありません。問題は、ユーザーがカメラ フィードをオンにしたままプログラムを終了した場合です。これが発生した場合、プロセスは永久に実行し続けるか、セグメンテーション違反エラーをスローします。

ドキュメントを検索し、それに従って:

QtConcurrent::run() によって返される QFuture は、キャンセル、一時停止、または進捗レポートをサポートしていないことに注意してください。返された QFuture は、実行中/終了ステータスと関数の戻り値を照会するためにのみ使用できます。

私は、それが最善かどうかわからないこの問題の修正を思いついたので、私よりも経験豊富な人からもう少し洞察を得たいと思っています。

基本的に、次のように closeEvent を再実装しました。

void MainWindow::closeEvent(QCloseEvent *event) {
    if(camera1->state() == AbstractGrabber::StoppedState)
        event->accept();
    else {
        camera1->stop();
        connect(camera1, SIGNAL(stateChanged(AbstractGrabber::State)),
            SLOT(exitWindow(AbstractGrabber::State)));
        event->ignore();
    }
}

そしてスロットで:

void MainWindow::exitWindow(AbstractGrabber::State grabberState) {
    if(grabberState == AbstractGrabber::StoppedState) this->close();
}

たぶん私は素朴ですが、これにはもっと良い解決策があるようです。経験のある人が私を助けてくれますか?

お時間をいただきありがとうございます。

4

3 に答える 3

1

ループは、カメラ フィードがシャットダウンまたは一時停止されているかどうかを既に確認しています。ユーザーがプログラムを閉じたかどうかを確認する別のチェックを追加してみませんか?

ちなみに、短期的なタスク用に設計されていますQtConcurrent::run()QRunnable無限ループ (パーマネント スレッド) の場合、公式ドキュメントではQThread代わりにhttp://qt-project.org/doc/qt-5/threads-technologies.htmlを使用することを推奨しています。

QThread でのループの再実装は次のとおりです。

// CameraThread subclasses QThread
CameraThread::run()
{
    while (!isStopRequest()
            && !isPauseRequest()
            && !this->isInterruptionRequested())
    {
        frame = captureFrame();

        //Do stuff
    }
}

終了するときは、return true を呼び出しQThread::requestInterruption()isInterruptionRequested()ループを中断します。

于 2014-08-07T09:17:48.107 に答える
1

スレッドが終了するまで、クラスのデストラクタで待機できます。これは、 を使用して実行できますQFuture::waitForFinished ()。スレッドの未来をクラスメンバーとして持つことができます:

QFuture<void> future;

そして、次の方法で新しいスレッドで関数を実行します。

future = QtConcurrent::run(this,&MyClass::myFunction);

停止要求を送信した後のデストラクタでは、スレッドが終了するのを待つことができます:

camera1->stop();

if(future.isRunning())
    future.waitForFinished();
于 2014-08-07T05:23:37.750 に答える