Displaying a Large PDF without Freezing the UI Thread
-
Hi everyone,
I am having some problems displaying a large PDF file using a Loader. I have a sample code below:
When the Load button is pressed in the code below, a large PDF file is displayed using PdfMultiPageView. I also make an AnimatedImage visible when the Loader is loading the component. However, since the PDF is a large file, the UI thread probably freezes when creating the PDF elements.
Do you have any suggestions for cases like this?
I am aware that using Qt.callLater is useful for operations with loops that take a long time, but this case is a little bit different.
Thanks in advance.
import QtQuick import QtQuick.Pdf import QtQuick.Controls Window { width: 500 height: 500 visible: true title: "PdfTest" Rectangle { anchors.fill:parent Loader{ id: loader anchors.fill: parent asynchronous: true sourceComponent: undefined onLoaded: loadingImg.visible = false } Component{ id: pmvComp PdfMultiPageView{ document: PdfDocument{ source: 'LARGE_PDF_FILE.pdf'} // some Pdf with 20 MB size } } AnimatedImage { id: loadingImg anchors.centerIn: parent source: "loading.gif" width:50 height:50 visible:false } Button{ anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: parent.bottom anchors.bottomMargin: 10 text: loader.sourceComponent == undefined ? "Load":"Unload" onClicked: { if(loader.sourceComponent == undefined){ loadingImg.visible = true loader.sourceComponent = pmvComp } else{ loader.sourceComponent = undefined } } } } } -
Hey, can someone please reply to this? I'm trying to load a PDF in a Qt Widget application using threading. Irrespective of what I do, it fails to load the PDF. I tried creating a concurrent thread, made a new QPdfDocument, loaded a PDF into the entity and then moved it to the main thread before returning the pointer. It still doesn't work! Here is an MWE (I know that the PDF loading in this example is synchronous, but even this fails to work - forget about loading the PDF asynchronously):
QFuture<QPdfDocument*> future = QtConcurrent::run([](){ QPdfDocument* loadDoc = new QPdfDocument(); loadDoc->load(ProjectSettings::instance().pdfPath); loadDoc->moveToThread(QApplication::instance()->thread()); return loadDoc; }); m_document = future.result(); -
Hey, can someone please reply to this? I'm trying to load a PDF in a Qt Widget application using threading. Irrespective of what I do, it fails to load the PDF. I tried creating a concurrent thread, made a new QPdfDocument, loaded a PDF into the entity and then moved it to the main thread before returning the pointer. It still doesn't work! Here is an MWE (I know that the PDF loading in this example is synchronous, but even this fails to work - forget about loading the PDF asynchronously):
QFuture<QPdfDocument*> future = QtConcurrent::run([](){ QPdfDocument* loadDoc = new QPdfDocument(); loadDoc->load(ProjectSettings::instance().pdfPath); loadDoc->moveToThread(QApplication::instance()->thread()); return loadDoc; }); m_document = future.result();@Bubu-Droid
Obviously to start with:- QPdfDocument::Error QPdfDocument::error() const (and statusChanged(QPdfDocument::Status status)). This is vital and first thing you should check.
- Verify
ProjectSettings::instance().pdfPathexists. - Have you tried multiple/absolute minimal PDF documents?
- Get rid of any concurrency/moveToThread.
- Is it safe/sensible to call
loadDoc->moveToThread()whileloadDoc->load()is running? Even if it is allowed, why/what is the effect of setting off a load before moving to a thread?