2016-11-21 10 views
1

私はQtを初めて利用しています。私はワーカースレッドがstd::threadです。ワーカースレッド関数はループ内のいくつかのデータを連続的にフェッチします。データのサイズは、UIのQMLText要素で頻繁に更新されます。私はstd::function以外のリスナーコールバックを持っており、thread's functionから呼び出されます。それは、私がText要素をQMLに更新したコールバックを送信します。私はsignal slotメカニズムを使用してそれを更新します。続いワーカースレッドからQt ::シグナルを送信すると、デフォルトでメインスレッドがUIを更新しますか?

QML : Text要素である:

Text { 
    id: mytext 
    objectName: "mytextobject" 

    function slotUpdateData(someValue){ 
    mytext = someValue 
    } 
} 
SignalUpdateData

QML側に存在するslotUpdateDataに接続されています。 std::threadからデータイベントコールバックを取得するたびに、にQML Text elementを更新する私はemit SignalUpdateDataです。続き

void CallBackReceivedFromWorkerThread(float someValue) { 
    emit SignalUpdateData(someValue) 
} 

は私がQML slot

QObject::connect(this, SIGNAL(SignalUpdateData(QVariant)), myTextItemQObject, SLOT(slotUpdateData(QVariant))); 

そして、このすべてが正常に動作して、このC++ signalが接続されている方法です。クラッシュ、ロックアップ、何もありません。

私の理解しているように、ワーカースレッドの関数はコールバックをトリガーしているので、コールバックを受け取ったときに実行制御がワーカースレッド上にあります。したがって、emit SignalUpdateData(someValue)を実行すると、we'erはワーカースレッドに残ります。 私の以前の経験で知っている限り、android & javaのように、アプリケーションのmain thread以外の場所からUIをアップデートすることはできません。

だから、これはどのように機能しますか? emit SignalUpdateData(someValue)main UI thread's event loopにコールしていますか?私はworker threadから電話していますが、Qtはまだmain threadにUIを変更していますか?私のアプローチがうまくいけば、それはパフォーマンスに影響しますか?これを行うための最良の推奨は何ですか?

私はこの&ないこれが機能することについてちょうど幸運については非常に確認したいです。最良のアプローチのためにQt::Connection_enumも使用する必要がありますか?

+1

私が知っている限り(間違っているかもしれない)、すべてのQMLはメイン/ GUIスレッド上で発生します。 –

答えて

7

あなたはQtを利用しています。そして、あなたは偶然にそれにぶつかりました。それはまともなデザインの兆候です。あなたのために、あなたのために、Qtのために:

Qtは動作させるために設計されており、あなたはこの特定のケースであなたを手伝ってくれるデフォルトの自動接続を使用しています。だからあなたは何事も正しいことをしていることがあります。何も変えないでください!

信号を送信すると、Qtは関連する送信元オブジェクトと宛先オブジェクトのミューテックスを取得し、受信オブジェクトのthread()QThread::currentThread()と比較します。それらが同一である場合、スロット/ファンクタは直ちに呼び出されます。シグナルの本体で発生するため、信号が返る前にスロットが呼び出されます。安全な場所にあるthread()からターゲットオブジェクトが使用されるため、これは安全です。

target->thread() != QThread::currentThread()の場合は、QMetaCallEventがターゲットオブジェクトにキューイングされます。このイベントには、スロットメソッドポインタとスロットによって渡されたパラメータのコピーが含まれています。 QObject::event実装はイベントを処理し、呼び出しを実行します。キューに入れられたイベントをオブジェクトに渡すことがジョブであるため、ターゲットオブジェクトのスレッドのイベントループはコールスタック上にあります。

上記のことは、簡単に言えば、Qt::AutoConnectionの意味です。 Qt::QueuedConnectionを使用している場合、2番目のケースはスレッドの内容に関係なく適用されます。 Qt::DirectConnectionを使用している場合、第1のケースは何に関係なく適用されます。

私の推測では、SOのQt関連の質問では、非自動接続タイプの使用の95%が不必要であり、理解の欠如と魔法の呪文に頼るものに頼っています。

+0

Qtのソースコードでこれらのものがどこに実装されているのか、それとも大規模に指摘できますか? – Paul

+0

@Paulほとんどの場合、['QObject'](https://code.woboq.org/qt5/qtbase/src/corelib/kernel/)の実装にあります。もちろん、メタデータシステムと連携しています。 –

+1

http://code.qt.io/cgit/qt/qtbase.git/tree/src/corelib/kernel/qobject.cpp#n3690 – BaCaRoZzo

関連する問題