0

我是 QT(占碑)的新手。我有一个非常简单的 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 中使用 QT,而是在 C++ 中使用过,所以我不能给你示例代码,但是这个页面应该会有所帮助:

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 回答