PDA

View Full Version : Using DrawText on a QImage in a QThread



D_N_R
12th April 2007, 22:36
Hello,

I've been spending a week to find a solution to this issue, there's definitly no way to write some text outside of the main GUI thread. Each time I tried, I got a "Xlib: unexpected async reply" error on the call to drawText() method.

I thought to use a signal/slot mechanism : it works when the signal is emited from the main GUI thread, but the problem is that I can't do this in my application because it's meant to be a server and its goal is to create a QImage with drawings and also some text, when a client requests it.

Recently I've been reading this page :

http://www.mizi.com/developer/mz20/413thread.htm
It states that there was some handlers in Qt3 to help synchronizing with the XLib, but I can't find them anymore in Qt4. Does anyone know any replacement mechanism ?

Thanks for your feedback

D_N_R

marcel
12th April 2007, 23:52
Do you call drawText from the GUI thread on the QImage from the worker thread, or from the worker thread as response to a main thread signal?

marcel
13th April 2007, 00:00
This is it ( from Assistant ):


When using QPainter (http://www.qtcentre.org/forum/qpainter.html) on a QImage, the painting can be performed in another thread than the current GUI thread, that is except rendering text (because QFont (http://www.qtcentre.org/forum/qfont.html) is GUI dependent). To render text in another thread, the text must first be derived as a QPainterPath (http://www.qtcentre.org/forum/qpainterpath.html) in the GUI thread.


You can use QPainterPath::addText( const QPointF&, const QFont&, const QString& ). But be careful when computing the text baseline, because your text's left end baseline will be at the QPointF passed to addText.

Next, all you have to do is give the other thread this QPainterPath to draw it.

D_N_R
13th April 2007, 14:28
You're right, QPainterPath does work when it is instanciated in the main GUI thread and another thread calls drawPath(). But as my application is a server to draw images, I'm looking for a way to modify the text/fonts to draw in function of the requests (each request is treated in its own thread).

I thought of sending some signal to a QObject instanciated in the main thread to update a QPainterPath, but actually, the main thread of my server is a thread manager and it's waiting for some client requests. So it can't deal with any signal to modify a QPainterPath as it hasn't any QApplication::exec() running.

I'm still stucked with this problem.

marcel
13th April 2007, 15:00
Call QThread::exec() in your thread manager's run method, and reimplement QObject::event in this thread. The clients should not use signals/slots to talk to the thread manager, but they should post events in it's event queue. Then, the server should create a QPainterPath for the client that posted the request.

You can find more about this in the events documentation.

Regards.