Non GUI thread use
-
I make an unusual use of Qt: I've developped a Qt based library and I want to provide its services to Java too using a JNI (in addition to a standard C++ API).
Here is how it currently works:
when the library is initalized in the context of a stand-alone application, it creates a QGraphicsScene which is rendered in a QGraphicsView when the library is initalized in a Java context, it creates a QGraphicsScene which is rendered in a QImage at Java client requestIn both cases, I create a QApplication but in the Java context, I don't call QApplication::exec().
The QGraphicsScene is modified by the time task of a QTimer.
In the Java context, a QMutex ensures that the time task and the Java client request to get the scene bitmap data don't collide.It basically works but it also crashes randomly and here is my current investigation state.
First of all, I've replaced the QPixmap with QImage since the final QImage rendering is made outside a GUI thread (and Qt complained about that).Now there is a single remaining warning at client startup:
"QCoreApplication::sendPostedEvents: Cannot send posted events for objects in another thread"Here is the code of the Java context rendering scheme:
@
QImage image (w, h, QImage::Format_ARGB32_Premultiplied);
QPainter painter(&image);
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
fScene->render(&painter);
painter.end();
@Note that it doesn't crash when I comment out the 'render' call.
I don't get anymore warning from Qt and the developer documentation only talks about QWidget that should not be used in a non GUI thread. Most of the crashes occur when modifying a QGraphicsSceneBspTreeIndex (or QGraphicsSceneBspTreeIndexPrivate) object.
It looks like there are remaining unsafe operations called. Any help would be greatly appreciated.[edit: fixed paragraphs -mariusg]
-
If you do not start the main event loop with QApplication::exec() the posted events cannot be delivered between threads. That's the cause for the startup warning.
Regarding the crashe, I don't have any clue, why this happens. Does the program work if you call it in Java mode without actually using Java (i.e. have a Qt test program, that calls your app in Java mode)?
-
Sorry, I've already posted a reply before but it seems to be lost...
[quote author="Volker" date="1291895376"]If you do not start the main event loop with QApplication::exec() the posted events cannot be delivered between threads. That's the cause for the startup warning.[/quote]
I don't think that's the reason of the crash. Anyway, I can't call exec() outside the main thread (got a warning).[quote author="Volker" date="1291895376"]Regarding the crashe, I don't have any clue, why this happens. Does the program work if you call it in Java mode without actually using Java (i.e. have a Qt test program, that calls your app in Java mode)?[/quote]
That's a good idea, but the behavior changes:
when I call QApplication::exec(), everything works fine
when I don't, it looks like my QTimer doesn't work, but if I call my time task manually, everything works fine
The latter could be logically explained since there is no application call to post the events (including the timer events). However, the question is "why does it work in Java?"
Note that when I say "everything works fine", I don't make real graphic rendering, I only request the QImage data into a custom buffer (like the JNI do).
I need to investigate more and to carefully check the various contexts.
Thanks for your help.