6

私はexec()自分のコードを呼び出していませんが、timerandQUdpSocketは正常に動作しています。が続くexec()のを待つために使用されますか?event

更新:は機能していました。これは、 を呼び出してtimerいなかったためです。つまり、はまだ の一部でした。まあ私はポーリングを使用しています。したがって、 で動作する必要はありませんでした。moveToThread(this)QThreadQThreadmain threadQUdpSocketfunctionssignals

ヒント: 何かを実行する必要がある場合はinit、 に が必要です。 が不要になるまで呼び出すことができevent loopます。これは、プログラムのロード時に実用的です。また、コンストラクターで呼び出す必要はありません (たとえば、内部で呼び出すこともできます)。ポインターを変数にコピーし、ポインターを使用して後で/他の場所を作成するだけです。QThreaddelaymoveToThreadsignalsrun()this QThreadcall

4

3 に答える 3

4

タイマーとソケットは、おそらく を呼び出したときに開始されるメイン イベント ループを使用していますQCoreApplication::exec()スレッド内でイベント ループを実行する正当な理由があることは確かですが、思いつきません。

QThreadのドキュメントには次のように記載されています。

各 QThread は、独自のイベント ループを持つことができます。exec(); を呼び出すことで、イベント ループを開始できます。exit() または quit() を呼び出すことで停止できます。スレッド内にイベント ループがあると、キュー接続と呼ばれるメカニズムを使用して、他のスレッドからのシグナルをこのスレッド内のスロットに接続できます。また、QTimer や QTcpSocket など、イベント ループを必要とするクラスをスレッドで使用できるようにします。ただし、スレッド内でウィジェット クラスを使用することはできないことに注意してください。

イベント ループがなければ、GUI スレッド、またはイベント ループを含む別のスレッドによって処理されるシグナルを送信することができます。これは、スレッドのスロットが有効になるためには、スレッドにイベント ループが必要であることを意味します。上記のドキュメントによると、 QTimerなどの一部のクラスでは、 を呼び出す必要がある実行中のイベント ループが必要ですQThread::exec()QTCPSocketなどの他のクラスには、使用する関数に応じて、イベント ループの有無にかかわらず実行する機能があります。クラスのドキュメントには、クラスに必要な要件があればそれを示す必要があります。

于 2010-02-26T06:18:50.820 に答える
2

実際にスレッドを使用するには、QApplication 実行ループの代わりにmoveToThread(this)、スレッド コンストラクター内で呼び出しrun()、QThread 派生クラスの保護されたメソッド内に実行ループを配置する必要があります。

スレッド実行ループを分離することで、QApplication ループが非 UI 関連のシグナルとスロットで乱雑になり、.eg ボタン クリックのスロット実行が遅れてアプリケーションが「ラグ」になるのを防ぎます。

注: 通常、常にQThread をサブクラス化します。詳細については、 Qt docを参照してください。

編集: Qt doc が間違っています。このスレッドを読んでください https://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/

于 2010-02-26T09:04:19.593 に答える
1

それはあなたのプログラムに依存します。次に例を示します。

void MyThread::run(){
  Curl * curl = new Curl();
  connect( curl, SIGNAL(OnTransfer(QString)), this, SLOTS(OnTransfer(QString)) );
  connect( curl, SIGNAL(OnDone()), curl, SLOTS(deleteLater()) );
  curl->Download("http://google.com");
  exec(); // this is an event loop in this thread, it will wait until you command quit()
}

void MyThread::OnTransfer(QString data){
  qDebug() << data;
}

exec() がないと、OnTransfer は呼び出されません。しかし、これを使用してcurlを外部で実行する場合(MyThreadの親がメインスレッドであると仮定)を親として:

MyThread::MyThread(){
  curl = new Curl(this);
  connect( curl, SIGNAL(OnTransfer(QString)), this, SLOTS(OnTransfer(QString)) );
  start();
}
void MyThread::run(){
  curl->Download("http://google.com");
}

これは期待どおりに機能します。OnTransfer が呼び出されます。

于 2010-08-16T07:08:10.187 に答える