はじめに:
マルチスレッド Qt アプリケーションは、プロセスが実行されている状況に遭遇する可能性があります。メイン ウィンドウ内の情報はセカンダリ スレッドから更新する必要があります。ただし、別のスレッドからメイン ウィンドウ UI に直接アクセスすることはお勧めできません。この記事では、スレッド シグナルとスロットを利用して、別のスレッドからメイン ウィンドウを安全に更新する方法について説明します。
問題ステートメント:
提供されたコードでは、mythread クラス別のスレッドからメイン ウィンドウのhorizontalLayout_4にQLabelを追加しようとします。ただし、ana->ui->horizontalLayout_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>
この例では:
このアプローチを使用すると、UI の変更が実行されます。メインスレッドでプロセスを開始しながら、別のスレッドからプロセスを開始します。これにより、スレッドの安全性が確保され、別のスレッドからメイン ウィンドウの UI にアクセスする際の潜在的な問題が防止されます。
以上がQt メイン ウィンドウを別のスレッドから安全に更新するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。