ホームページ >バックエンド開発 >C++ >Qt メイン ウィンドウを別のスレッドから安全に更新するにはどうすればよいですか?

Qt メイン ウィンドウを別のスレッドから安全に更新するにはどうすればよいですか?

DDD
DDDオリジナル
2024-10-26 13:52:31843ブラウズ

How to Safely Update a Qt Main Window from a Different Thread?

Qt - 別のスレッドからメイン ウィンドウを更新する

はじめに:

マルチスレッド Qt アプリケーションは、プロセスが実行されている状況に遭遇する可能性があります。メイン ウィンドウ内の情報はセカンダリ スレッドから更新する必要があります。ただし、別のスレッドからメイン ウィンドウ UI に直接アクセスすることはお勧めできません。この記事では、スレッド シグナルとスロットを利用して、別のスレッドからメイン ウィンドウを安全に更新する方法について説明します。

問題ステートメント:

提供されたコードでは、mythread クラス別のスレッドからメイン ウィンドウのhorizo​​ntalLayout_4にQLabelを追加しようとします。ただし、ana->ui->horizo​​ntalLayout_4->addWidget(label) 行はコンパイルに失敗します。

解決策:

この問題に対処するには、より適切なアプローチは、メイン ウィンドウのスロット内に UI 変更を配置し、スレッド信号をそのスロットに接続することです。これにより、GUI 機能がメイン スレッドに残り、他のスレッドからシグナルを受け取ることができるようになります。

例を次に示します。

メイン UI (MainUI.h および MainUI.cpp):

<code class="cpp">class MainUI : public QWidget
{
    Q_OBJECT

public:
    explicit MainUI(QWidget *parent = 0) : QWidget(parent)
    {
        // Initialize layout and thread
        layout = new QHBoxLayout(this);
        setLayout(layout);

        QThread *thread = new QThread(this);
        GUIUpdater *updater = new GUIUpdater();
        updater->moveToThread(thread);

        // Connect thread signal to main window slot
        connect(updater, SIGNAL(requestNewLabel(QString)), this, SLOT(createLabel(QString)));
        connect(thread, SIGNAL(destroyed()), updater, SLOT(deleteLater()));

        // Initiate label creation from thread
        updater->newLabel("path/to/image.png");
    }

public slots:
    void createLabel(const QString &imgSource)
    {
        // Create and add label to layout in main thread
        QPixmap i1(imgSource);
        QLabel *label = new QLabel(this);
        label->setPixmap(i1);
        layout->addWidget(label);
    }

private:
    QHBoxLayout *layout;
};</code>

ワーカー オブジェクト (GUIUpdater.h および GUIUpdater.cpp):

<code class="cpp">class GUIUpdater : public QObject
{
    Q_OBJECT

public:
    explicit GUIUpdater(QObject *parent = 0) : QObject(parent) {}

    void newLabel(const QString &image)
    {
        // Emit signal to main window
        emit requestNewLabel(image);
    }

signals:
    void requestNewLabel(const QString &);
};</code>

この例では:

  • MainUI は UI 更新を受け取るメイン ウィンドウです。
  • GUIUpdater は別のスレッドで作成されたワーカー オブジェクトです。
  • GUIUpdater::newLabel が別のスレッドから呼び出されると、requestNewLabel が発行されます。
  • MainUI.createLabel スロットは requestNewLabel シグナルに接続されており、メイン スレッド内で GUI の更新を安全に実行できます。

このアプローチを使用すると、UI の変更が実行されます。メインスレッドでプロセスを開始しながら、別のスレッドからプロセスを開始します。これにより、スレッドの安全性が確保され、別のスレッドからメイン ウィンドウの UI にアクセスする際の潜在的な問題が防止されます。

以上がQt メイン ウィンドウを別のスレッドから安全に更新するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。