2010-05-17 9 views
1

J'essaie de créer une fenêtre principale Qt à partir de Java en utilisant JNI directement et j'ai eu une erreur de threading.Création d'une QMainWindow à partir de Java en utilisant JNI

Mon code ressemble à ceci:

classe Test:

public class Test 
{ 
    public static void main(String... args) 
    { 
     System.out.println(System.getProperty("java.library.path")); 
     TestWindow f = new TestWindow(); 
     f.show(); 
    } 
} 

classe TestWindow:

public class TestWindow 
{ 
static { System.loadLibrary("mylib"); } 

public native void show(); 
} 

C++ impl:

void JNICALL Java_testpackage_TestWindow_show 
    (JNIEnv *, jobject) 
{ 
    int c = 0; char** a = NULL; 
    QApplication* app = new QApplication(c, a); 
    QMainWindow* mw = new QMainWindow(); 
    mw->setWindowTitle("Hello"); 
    mw->setGeometry(150, 150, 400, 300); 
    mw->show(); 
    QApplication::exec(); 
} 

et je reçois ma fenêtre peinte mais congelé (il ne reçoit aucun événement) et le message d'erreur suivant lors de l'instanciation l'objet QMainWindow:

QCoreApplication::sendPostedEvents: Cannot send posted events for objects in another thread 

Je sais que toutes les opérations de l'interface utilisateur doit faire dans le thread d'interface utilisateur, mais dans mon exemple, je créé le QApplication dans le seul fil que je l'ai en cours d'exécution, donc, Tout devrait fonctionner correctement.

J'ai fait quelques tests en exécutant le code de ma méthode "show" à partir d'un objet QMetaObject :: invokeMethod en utilisant Qt :: QueuedConnection mais rien ne fonctionne correctement.

Je sais que je pourrais utiliser Jambi ... mais je sais que cela pourrait se faire en mode natif aussi, et c'est ce que je veux faire :)

Toutes les idées sur ce sujet? Merci d'avance!

Ernesto

Répondre

0

La solution était très naïve:

Je ne savais pas que je devais commencer la machine virtuelle Java avec le paramètre:

-XstartOnFirstThread 

Je l'ai fait et tout a fonctionné correctement.

1

Juste une suggestion *: peut-être vous devriez instancier une fenêtre native dans un thread séparé?

public class Test 
{ 
    public static void main(String... args) 
    { 
     System.out.println(System.getProperty("java.library.path")); 
     new Thread(new Runnable() { 
      public void run() { 
       TestWindow f = new TestWindow(); 
       f.show(); 
      } 
     }).start(); 
    } 
} 

* Je n'ai jamais programmé d'applications Java avec une interface graphique native. Peut-être devriez-vous envisager Swing ou SWF à la place?

Une autre suggestion est d'essayer de la JNA au lieu de JNI: https://github.com/twall/jna/

Questions connexes