2

私のプログラムには、テキストボックスとqthreadポインタを備えたウィジェットクラスがあります。qthreadポインターを使用して、アプリケーションに影響を与えることなく、テキスト選択によってテキストボックスを継続的に更新したいと思います。しかし、テキストボックスにアクセスできません。ただし、パラメータをqthreadに渡すことでテキストボックスにアクセスします。テキストボックスにアクセスしてテキスト選択を数回更新すると、アプリケーションが自動的に終了してエラーが表示されます

list_thread:../../src/XlibInt.c:596:_XPrivSyncFunction:アサーション `(dpy-> flags&(1L << 3))!=0'が失敗しました。

4

1 に答える 1

3

Qt では、メイン スレッドとは別のスレッドで GUI 関数を呼び出すことはできません (またはすべきではありません)。できることは、ワーカー スレッドでシグナルを送信し、メイン スレッドで受信することです。

たとえば、スレッドを作成した後に単に呼び出す場合

connect(thread, SIGNAL(newText(QString)), lineEdit, SLOT(setText(QString)));

デフォルトでは、これは type の接続を確立しますQt::AutoConnection。レシーバーが存在する同じスレッドでシグナルを発信するときはいつでも、それは単純な関数呼び出しと同等です。しかし、別のスレッド (新しいスレッドなど) でそのシグナルを発行すると、そのシグナルはキューに入れられ、メイン スレッドが再びスケジュールされたときに配信され、イベント ループが続行されるため、スロット関数は常にスレッドで呼び出されます。レシーバーが生きています。ただし、値パラメーター (ポインターまたは参照なし) を使用してシグナルを宣言するようにしてください。これによりQString、スレッドの文字列へのポインター/参照ではなく、実際にはのコピーが取得されます (スレッドによって既に上書きされている可能性があります)。

...
signals:
    void newText(QString);
...

as connection typeを使用して、送信後、レシーバーがシグナルの処理を終了する (スロット関数から返される) まで、スレッドが待機 (ブロック) するように接続を構成することもできますQt::BlockingQueuedConnection。しかし、あなたの場合、これは必要ありません。

詳細については、Qt の優れたドキュメントを参照してください。

于 2011-09-05T13:30:20.673 に答える