views:

151

answers:

1

I am new to QT(jambi). I have a very simple QTJambi (4.5.2) app. I am trying to figure out why this will not work (DoResponseReady never called) within a thread. Switch the static variable between threaded=true/false to reproduce.


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();
 } 
}
+1  A: 

Your thread doesn't have a QT event loop so nothing is going to happen.

I've not worked with QT in Java but rather c++ so I can't give you example code, but this page should help:

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

With that being said ... try this:

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

Note that this should just point you in the right direction, you'll need to deal with synchronization issues, etc. Also note the paragraph that talks about QObject ownership and threads (thread affinity).

In C++ I created a class that extends QThread and an abstract interface called "Worker". The QThread derived class takes the Worker object as an argument in the constructor and changes the affinity so that it's "owned" by that thread (see: moveToThread() ). Then in the overridden run() method, it calls the Worker::init() method after which it starts the event loop. I fire off whatever initial things need to be handled in the init() method, such as timers or network requests.

Brian Roach
Thank you. Although I have not verfied that is the issue, it helps point me into a direction. I will be back once I have verified.
CDSO1