2011-09-28 2 views
2

http://doc.qt.io/qt-5/qpointer.htmlによると、QPointerは非常に便利です。しかし、私はそれが次のコンテキストで非効率的である可能性が見つかりました:QPointerマルチスレッドプログラム

私は3回のラベルを表示したり、他の何かをしたい場合は、私は

if(label) label->show1(); if(label) label->show2(); if(label) label->show3();

の代わり を使用する必要がありますif(label) { label->show1();label->show2();label->show3(); }

他のスレッドの後label->show1(); o r label->show2();.

同じ機能を得るために3つのifs以外にも美しい方法がありますか?

もう1つの質問は、if(label)の後にラベルが破棄された場合、if(label) label->show1();がまだ間違っていますか?

マルチスレッドプログラムでの経験はありません。どんな助けもありがとうございます。 ;)

+4

ラベルはif(label)とlabel-> show1()の間で破棄することもできます。 –

答えて

6

メイン/ GUIスレッド(つまり、QApplication :: exec()内のQtのイベントループを実行しているスレッド)からのみQWidgetsにアクセスできるようにするのが唯一の安全な方法だと思います。 。

異なるスレッド内で実行されているコードがあり、そのコードがQLabelを表示/非表示にしたい場合、そのコードはQEventオブジェクト(またはそのサブクラス)を作成し、qApp-> postEvent()を呼び出して、そのオブジェクトをメインスレッドに送信します。次に、QtイベントループがメインスレッドでそのQEventを取得して処理すると、コードがQLabelに安全に行うことができるポイントになります。

また、スレッドのコードでクロススレッド信号(here)を発行し、内部でイベントポストを処理させることができます。それはあなたの目的のために良いかもしれません。

0

いずれのアプローチもスレッドセーフではありません。最初のスレッドがifステートメントを実行した後、もう1つのスレッドがラベルを削除して、ifステートメント内に入り、クラッシュする可能性があります。

Qtには数多くのスレッド同期構造が用意されていますが、このプログラムで作業を続ける前に、QMutexで始まり、スレッドセーフについて詳しく知りたいと思うかもしれません。限り、あなたの他のスレッドは、あなたが表示している間に、同じミューテックスオブジェクトは、それはあなたのラベルを削除することを防止することが施錠使用しているよう

mutex.lock(); 
label1->show(); 
label2->show(); 
label3->show(); 
mutex.unlock() 

:ミューテックスを使用して

は、あなたの関数は次のようになりますになるだろうそれら。

+1

AFAIK Qtのルールは、「メインスレッド以外のスレッドからGUIオブジェクトに触れないでください」です。特に、QtのメインスレッドがそれらのQLabelに(親ウィジェットを介して)アクセスしていないという保証はないので、上記の呼び出しの周りにmutexロックを入れるイベントが十分であるかどうかはわかりません。 Qtはmutexをロックすることを知らないでしょう。 –

関連する問題