Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Displaying a Large PDF without Freezing the UI Thread
Qt 6.11 is out! See what's new in the release blog

Displaying a Large PDF without Freezing the UI Thread

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
3 Posts 3 Posters 846 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Serhan KarsS Offline
    Serhan KarsS Offline
    Serhan Kars
    wrote on last edited by Serhan Kars
    #1

    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
                        }
                }
            }
        }
    
    }
    
    1 Reply Last reply
    0
    • B Offline
      B Offline
      Bubu-Droid
      wrote last edited by
      #2

      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();
      
      JonBJ 1 Reply Last reply
      0
      • B Bubu-Droid

        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();
        
        JonBJ Offline
        JonBJ Offline
        JonB
        wrote last edited by JonB
        #3

        @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().pdfPath exists.
        • Have you tried multiple/absolute minimal PDF documents?
        • Get rid of any concurrency/moveToThread.
        • Is it safe/sensible to call loadDoc->moveToThread() while loadDoc->load() is running? Even if it is allowed, why/what is the effect of setting off a load before moving to a thread?
        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved