2012-01-26 29 views
4

QObjectのオブジェクトをQObject::moveToThreadのスレッドに移動すると、オブジェクトが受け取るすべてのシグナルがそのスレッド内で処理されます。しかし、スロットが直接呼び出された場合(object->theSlot())、呼び出しはブロックされます。スレッド内でその呼び出しを実行し、直ちに呼び出しスレッドに制御を戻す通常の方法は何でしょうか? QTimerのハックはカウントされません。単一の目的の接続を設定し、それをもう一度削除することは、他のすべてが失敗した場合には解決策になるかもしれません。QObject :: moveToThreadとそのスレッド内でメンバ関数を実行する

+0

に設定してあなたはQMetaObject::invokeMethodを使用することができます。その後、 'のQObject :: moveToThread'を使用して、それをしたいですか?そうでなければ、私はむしろすべての計算をシグナルを受け取らないオブジェクトに入れて、私のメソッドを使うでしょう... – UmNyobe

答えて

5

Qtの:: CONNECTIONTYPEはQtの:: QueuedConnection

+0

これは私が探しているものに非常に近いと思います。オブジェクトが既に別のスレッドにあると仮定して、これは 'AutoConnection'と同じように動作しませんか? – pmr

+0

あなたはそうです。 AutoConnectionは同じですが、しかし!私はいつもQMetaObject :: invokeMethodを使用する私の意図を知るために、この引数をコードに入れることを前提にしています –

0

QFuture<T> QtConcurrent::run (Function function, ...)を使用すると、別のスレッド内で実行を開始し、QFutureWatcherを使用して結果を取得できます。 movetoThreadに電話する必要はありません。

基本的には何か:

QFutureWatcher<T>* watch = new QFuture(0); 
connect(watch, SIGNAL(finished()), this, SLOT(handleResult())); 
QFuture<T> future = QtConcurrent::run(myObj, &QMyObject::theSlot(), args...); 
watch.setFuture(future); 
.... 

//slot 
private void handleResult(){ 
    if(future->isCancelled()) 
    return; 
    T mydata = watch->future()->result(); 
    // use your data as you want 
} 

QtConcurrent::runは、いくつかのスレッドで実行したことには、このオブジェクトのメソッドをスケジュールします。それはノンブロッキングです。一方、QFuture::result()は、計算がまだ進行中であれば、結果が得られるまでブロックします。そのため、finished()を使用して計算が終了したときに通知するには、もう一方のオブジェクトが必要です。私はQtであなたの問題のより良い設計を考えることができません。

+0

これは 'QtConcurrent'スレッドの文脈で' TheSlot'を実行し、 'MyObject 'のスレッドの文脈では実行しません'。 –

+0

はい、それは重要ですか?なぜ私は下落したのですか?結局のところ、彼は呼び出し側スレッドとは別のスレッドで 'theSlot()'を実行したいだけです。これはスレッドを作成してstartを呼び出すよりも優れています:[Qthread vs QRunnable](http://developer.qt.nokia.com/videos/watch/enhancing_your_qt_application_with_multiple_threads)私は 'pmr'を誤解しましたか? – UmNyobe

+0

私はあなたにdownvoteしなかった。あなたの代わりに 'moveToThread'を外して、他のすべてのスロットを非同期にします。それには欠点がありますが、それは特定の状況下ではまだ理にかなっています。私はトンのハックのために行くだろう。 – pmr

関連する問題