Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show paginated text from a QTextDocument in QML?

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).

like image 446
Inkane Avatar asked Nov 08 '22 09:11

Inkane


1 Answers

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.

like image 158
Inkane Avatar answered Nov 14 '22 21:11

Inkane