I currently have a C++ class inheriting from QQuickPaintedItem
. I use it to paint layouted, paginated richtext from a QTextDocument
via QTextDocument::drawContents
(or by directly calling its QTextDocumenLayout's draw
method).
However, as stated in QQuickPaintedItems
documentation, there are threading issues to be aware of:
Warning: Extreme caution must be used when creating QObjects, emitting signals, starting timers and similar inside this function as these will have affinity to the rendering thread.
Specifically, in this case, QTextDocumentLayoutPrivate
has timers which get started/stopped when QTextDocumenLayout::draw
is called. Unfortunately, the QTextDocument
and thus the timers lives in the qml main thread, while paint
is called in the render thread, leading to messages like
QBasicTimer::start: Timers cannot be started from another thread
While this doesn't affect the functionality of my application (so far), this is probably not a good thing™.
Therefore, my question is whether there is a better way to show the paginated text in QML (not necessarily involving QQuickPaintedItem
).
For now I'm still using the QQuickPaintedItem
and when paint
is called I do the following:
First check whether the QTextDocument
has its affinity set to its current thread. If yes, I'll proceed as normal.
Otherwise QMetaObject::invokeMethod
is used to call a method which moves the document to the rendering thread, and calls update
to trigger a repaint, which now works as the thread affinity is correct. At the end of paint
, the QTextDocument
's thread affinity is set back to the original thread.
This works as far as I can tell (as in, no more warnings), but feels conceptually rather wrong.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With