0

QT(jambi)は初めてです。私は非常にシンプルなQTJambi(4.5.2)アプリを持っています。スレッド内でこれが機能しない(DoResponseReadyが呼び出されない)理由を理解しようとしています。静的変数をthreaded=true/falseの間で切り替えて再現します。


import com.trolltech.qt.core.QByteArray;
import com.trolltech.qt.core.QUrl;
import com.trolltech.qt.gui.QApplication;
import com.trolltech.qt.gui.QPushButton;
import com.trolltech.qt.network.QNetworkAccessManager;
import com.trolltech.qt.network.QNetworkReply;
import com.trolltech.qt.network.QNetworkRequest;


public class Main {
 static boolean threaded = false;
 static Main main;

 public static void main(String[] args) {
  QApplication.initialize(args);
  main = new Main();  
  main.doit();
 }

 void DoResponseReady(QNetworkReply reply) {
  System.out.println("Response Ready");
 }

 void testnetwork_thread()
 {
  new Thread(new Runnable() {
   @Override
   public void run() {
    testnetwork();    
   }
  }).start();  
 }

 void testnetwork()
 {
  QNetworkAccessManager qnam = new QNetworkAccessManager();
  QNetworkRequest req = new QNetworkRequest(new QUrl("http://junkurl.neverwillwork.ok"));  
  QByteArray data = new QByteArray();
  qnam.finished.connect(main, "DoResponseReady(QNetworkReply)");
  qnam.post(req, data);    
 }

 void NetworkTest()
 {
  if (threaded)   
   testnetwork_thread();
  else
   testnetwork();
 }

 public void doit() {
        QPushButton quit = new QPushButton("Test");
        quit.clicked.connect(this, "NetworkTest()");
        quit.show();
        QApplication.exec();
 } 
}
4

1 に答える 1

1

スレッドにはQTイベントループがないため、何も起こりません。

私はJavaではなくc++でQTを使用したことがないため、サンプルコードを提供することはできませんが、このページは次のように役立ちます。

http://qt.nokia.com/doc/qtjambi-4.5.2_01/com/trolltech/qt/qtjambi-threads.html

それが言われていると...これを試してみてください:

void testnetwork_thread()
 {
  new Thread(new Runnable() {
   @Override
   public void run() {
    QEventLoop loop = new QEventLoop();
    testnetwork();    
    loop.exec();
   }
  }).start();  
 }

これは正しい方向を示しているだけで、同期の問題などに対処する必要があることに注意してください。また、QObjectの所有権とスレッド(スレッドアフィニティ)について説明している段落にも注意してください。

C ++では、QThreadを拡張するクラスと「Worker」と呼ばれる抽象インターフェイスを作成しました。QThread派生クラスは、コンストラクターの引数としてWorkerオブジェクトを受け取り、そのスレッドによって「所有」されるようにアフィニティーを変更します(moveToThread()を参照)。次に、オーバーライドされたrun()メソッドで、Worker :: init()メソッドを呼び出し、その後、イベントループを開始します。タイマーやネットワーク要求など、init()メソッドで処理する必要のある最初のものをすべて起動します。

于 2010-04-14T20:06:23.297 に答える