0

別のスレッドからQDialogに影響を与えたいのですが、次の2つのことを行う必要があります。

dialog->show();
dialog->raise();
dialog->activateWindow();

私が理解している限り、これらはイベントであるため、メインスレッドのイベントループで実行する必要があります。QApplication::postEvent私はこれを内で達成すると思いますQThread::run()。誰か確認できますか?

次に、その別のスレッドで処理された画像を表示したいと思います。ダイアログクラスをサブクラス化し、スレッドセーフ関数を作成する必要があると思います。この関数は...setImage()によって呼び出されpaintEvent()ます。しかし、これは不可能のようです。QMutex::unlock()?でpaintEventをブロックできません 誰かがいくつかの提案を提供できますか?


QApplication::postEvent(dialog, new QShowEvent());動作しませんでした。

これは、別のスレッドから(関数として)スロットを呼び出すためのソリューションです。

QMetaObject::invokeMethod(dialog, "show", Qt::QueuedConnection);
QMetaObject::invokeMethod(dialog, "raise", Qt::QueuedConnection);

...まだ作業中でactivateWindow()安全QThreadな機能。

したがって、のQImage場合、これはQPaintDeviceです。おそらくそれはスレッドセーフです。私のアプローチはQImage、スレッド内に設定されたクラスメンバーを持つことでした。その後、後でペイントします。

ただし、以下のアプローチも同様に優れていることに注意してください。

4

1 に答える 1

4

私はこれがあなたが望むことをするためのより明確な方法だと思います:

class Dialog : public QDialog
{
    ...
public slots:
    void showImage(QImage img);
    ...
}

void Dialog::showImage(QImage img);
{
    setImage(img);
    show();
    raise();
    activateWindow();
}

class Thread : public QThread
{
    ...
signals:
    void imageReady(QImage);
}

void Thread::run()
{
    QImage img;
    /// image processing stuff

    emit imageReady(img);
    ...
}


Thread *thread = new Thread;
Dialog *dialog = new Dialog;
connect(thread, SIGNAL(imageReady(QImage)), dialog, SLOT(showImage(QImage)));

thread->start();
于 2013-02-13T06:32:13.910 に答える