Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QTextDocument in thread issue
Forum Updated to NodeBB v4.3 + New Features

QTextDocument in thread issue

Scheduled Pinned Locked Moved Solved General and Desktop
22 Posts 5 Posters 2.7k 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.
  • SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on last edited by
    #12

    Based on the name, I would go with the Qt 4 sources of Assistant.

    Interested in AI ? www.idiap.ch
    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

    1 Reply Last reply
    0
    • eyllanescE eyllanesc

      @Cobra91151 QTextDocument should not live in a second thread so you get that error. QTextDocument will interact with QObjects that live in the main thread (for example QTextEdit, QPrinter, etc).

      Cobra91151C Offline
      Cobra91151C Offline
      Cobra91151
      wrote on last edited by
      #13

      @eyllanesc said in QTextDocument in thread issue:

      @Cobra91151 QTextDocument should not live in a second thread so you get that error. QTextDocument will interact with QObjects that live in the main thread (for example QTextEdit, QPrinter, etc).

      @eyllanesc

      I had QTextDocument in my main thread but setPlainText method freezes the GUI for a couple of seconds. So, I need to fix it. That is why I put it to the worker (second thread). Thanks.

      jsulmJ 1 Reply Last reply
      0
      • Cobra91151C Cobra91151

        @eyllanesc said in QTextDocument in thread issue:

        @Cobra91151 QTextDocument should not live in a second thread so you get that error. QTextDocument will interact with QObjects that live in the main thread (for example QTextEdit, QPrinter, etc).

        @eyllanesc

        I had QTextDocument in my main thread but setPlainText method freezes the GUI for a couple of seconds. So, I need to fix it. That is why I put it to the worker (second thread). Thanks.

        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #14

        @Cobra91151 Qt UI classes should not be used in other threads than main (UI) thread!
        How big is the text you're trying to load?

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        Cobra91151C 1 Reply Last reply
        1
        • jsulmJ jsulm

          @Cobra91151 Qt UI classes should not be used in other threads than main (UI) thread!
          How big is the text you're trying to load?

          Cobra91151C Offline
          Cobra91151C Offline
          Cobra91151
          wrote on last edited by
          #15

          @jsulm

          It is 280 pages for printing. I run some debugging and found out that setPlainText does not lead to such issue. The actual problem is with print method. It takes too much time to paint all these pages to the QPrintPreviewDialog.

          Code:

          connect(printPreviewDlg, &QPrintPreviewDialog::paintRequested, this, [txtDoc](QPrinter *printer) {
                  txtDoc->print(printer);
          });
          

          I will subclass the QTextDocument and reimplement the print method to display some progress dialog. Thanks.

          1 Reply Last reply
          0
          • Cobra91151C Offline
            Cobra91151C Offline
            Cobra91151
            wrote on last edited by
            #16

            Nope, it does not work. The progress dialog still freezing.

            jsulmJ 1 Reply Last reply
            0
            • Cobra91151C Cobra91151

              Nope, it does not work. The progress dialog still freezing.

              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote on last edited by
              #17

              @Cobra91151 Can you show ther code?

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              Cobra91151C 1 Reply Last reply
              0
              • jsulmJ jsulm

                @Cobra91151 Can you show ther code?

                Cobra91151C Offline
                Cobra91151C Offline
                Cobra91151
                wrote on last edited by
                #18

                @jsulm

                Yes, I will create the test example and post it soon. Thank you.

                JonBJ 1 Reply Last reply
                0
                • Cobra91151C Cobra91151

                  @jsulm

                  Yes, I will create the test example and post it soon. Thank you.

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by JonB
                  #19

                  @Cobra91151
                  Also for 280 pages just how long does it take/freeze? Oh you said "a couple of seconds". Does your end-user not have the patience to wait 2 seconds for 280 pages? :) If the user prints to printer how long does it take? Users are over-pampered these days....

                  Cobra91151C 1 Reply Last reply
                  0
                  • JonBJ JonB

                    @Cobra91151
                    Also for 280 pages just how long does it take/freeze? Oh you said "a couple of seconds". Does your end-user not have the patience to wait 2 seconds for 280 pages? :) If the user prints to printer how long does it take? Users are over-pampered these days....

                    Cobra91151C Offline
                    Cobra91151C Offline
                    Cobra91151
                    wrote on last edited by
                    #20

                    @jsulm @JonB

                    Here is my test example:

                    printexample.h

                    #ifndef PRINTEXAMPLE_H
                    #define PRINTEXAMPLE_H
                    
                    #include <QWidget>
                    #include <QPushButton>
                    #include <QHBoxLayout>
                    #include <QThread>
                    #include <QPrinter>
                    #include <QPrintPreviewDialog>
                    #include <QToolBar>
                    #include <QTextDocument>
                    #include <QDebug>
                    #include "printworker.h"
                    
                    class PrintExample : public QWidget
                    {
                        Q_OBJECT
                    
                    public:
                        PrintExample(QWidget *parent = nullptr);
                        ~PrintExample();
                    
                    private slots:
                        void printData();
                        void setPrintPreviewData(QString printData);
                        void setPreviewDataGenerationFailed();
                    
                    private:
                        QLayout *printLayout(QPushButton *btn);
                    };
                    #endif // PRINTEXAMPLE_H
                    

                    printexample.cpp

                    #include "printexample.h"
                    
                    PrintExample::PrintExample(QWidget *parent)
                        : QWidget(parent)
                    {
                        setWindowTitle("Print example");
                        setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
                        setFixedSize(500, 400);
                        QPushButton *printBtn = new QPushButton("Print", this);
                        printBtn->setFixedSize(120, 50);
                        connect(printBtn, &QPushButton::clicked, this, &PrintExample::printData);
                        setLayout(printLayout(printBtn));
                    }
                    
                    QLayout *PrintExample::printLayout(QPushButton *btn)
                    {
                        QHBoxLayout *btnLayout = new QHBoxLayout();
                        btnLayout->setAlignment(Qt::AlignHCenter);
                        btnLayout->addWidget(btn);
                        return btnLayout;
                    }
                    
                    void PrintExample::printData()
                    {
                        //This is just test example data
                        QString testBigData = "QTextDocument is a container for structured rich text documents, providing support for styled text and various types of document elements, such as lists, tables, "
                                              "frames, and images. They can be created for use in a QTextEdit, or used independently. Each document element is described by an associated format object. "
                                              "Each format object is treated as a unique object by QTextDocuments, and can be passed to objectForFormat() to obtain the document element that it is applied to. "
                                              "A QTextDocument can be edited programmatically using a QTextCursor, and its contents can be examined by traversing the document structure. "
                                              "The entire document structure is stored as a hierarchy of document elements beneath the root frame, found with the rootFrame() function. "
                                              "Alternatively, if you just want to iterate over the textual contents of the document you can use begin(), end(), and findBlock() to retrieve text blocks that you can "
                                              "examine and iterate over. The layout of a document is determined by the documentLayout(); you can create your own QAbstractTextDocumentLayout subclass and set it using "
                                              "setDocumentLayout() if you want to use your own layout logic. The document's title and other meta-information can be obtained by calling the metaInformation() "
                                              "function. For documents that are exposed to users through the QTextEdit class, the document title is also available via the QTextEdit::documentTitle() "
                                              "function. The toPlainText() and toHtml() convenience functions allow you to retrieve the contents of the document as plain text and HTML. "
                                              "The document's text can be searched using the find() functions. Undo/redo of operations performed on the document can be controlled using the setUndoRedoEnabled() "
                                              "function. The undo/redo system can be controlled by an editor widget through the undo() and redo() slots; the document also provides contentsChanged(), "
                                              "undoAvailable(), and redoAvailable() signals that inform connected editor widgets about the state of the undo/redo system. "
                                              "The following are the undo/redo operations of a QTextDocument.";
                        QThread *printDataThread = new QThread();
                        PrintWorker *printWorker = new PrintWorker();
                        printWorker->moveToThread(printDataThread);
                        connect(printWorker, &PrintWorker::generatedPreviewData, this, &PrintExample::setPrintPreviewData);
                        connect(printWorker, &PrintWorker::previewDataGenerationFailed, this, &PrintExample::setPreviewDataGenerationFailed);
                        connect(printWorker, &PrintWorker::finished, printDataThread, &QThread::quit);
                        connect(printWorker, &PrintWorker::finished, printWorker, &PrintWorker::deleteLater);
                        connect(printDataThread, &QThread::finished, printDataThread, &QThread::deleteLater);
                        QMetaObject::invokeMethod(printWorker, "generatePrintPreview", Q_ARG(QString, testBigData));
                        printDataThread->start();
                    }
                    
                    void PrintExample::setPrintPreviewData(QString printData)
                    {
                        QPrinter *previewPrinter = new QPrinter(QPrinter::HighResolution);
                        previewPrinter->setOutputFormat(QPrinter::NativeFormat);
                        previewPrinter->setPaperSize(QPrinter::A4);
                        previewPrinter->setPageMargins(QMarginsF(15, 15, 15, 15));
                        QPrintPreviewDialog *printPreviewDlg = new QPrintPreviewDialog(previewPrinter, this);
                        printPreviewDlg->setGeometry(100, 100, 700, 500);
                        printPreviewDlg->setMinimumSize(700, 500);
                        printPreviewDlg->setWindowModality(Qt::ApplicationModal);
                        printPreviewDlg->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
                        printPreviewDlg->installEventFilter(this);
                        QFont docFont;
                        docFont.setPointSize(14);
                        QTextDocument *textDoc = new QTextDocument(this);
                        textDoc->setDefaultFont(docFont);
                        textDoc->setPlainText(printData);
                        connect(printPreviewDlg, &QPrintPreviewDialog::paintRequested, this, [this, textDoc](QPrinter *printer) {
                            textDoc->print(printer);
                        });
                        connect(printPreviewDlg, &QPrintPreviewDialog::finished, this, [textDoc, previewPrinter, printPreviewDlg]() {
                            textDoc->deleteLater();
                            delete previewPrinter;
                            printPreviewDlg->deleteLater();
                        });
                        printPreviewDlg->show();
                    }
                    
                    void PrintExample::setPreviewDataGenerationFailed()
                    {
                        //Failed to generate preview
                    }
                    
                    PrintExample::~PrintExample()
                    {
                    
                    }
                    

                    printworker.h:

                    #ifndef PRINTWORKER_H
                    #define PRINTWORKER_H
                    
                    #include <QObject>
                    
                    class PrintWorker : public QObject
                    {
                        Q_OBJECT
                    public:
                        explicit PrintWorker(QObject *parent = nullptr);
                    
                    public slots:
                        void generatePrintPreview(QString previewData);
                    
                    signals:
                        void generatedPreviewData(QString data);
                        void previewDataGenerationFailed();
                        void finished();
                    };
                    
                    #endif // PRINTWORKER_H
                    

                    printworker.cpp:

                    #include "printworker.h"
                    
                    PrintWorker::PrintWorker(QObject *parent) : QObject(parent)
                    {
                    
                    }
                    
                    void PrintWorker::generatePrintPreview(QString previewData)
                    {
                        if (!previewData.isEmpty()) {
                            emit generatedPreviewData(previewData);
                        } else {
                            emit previewDataGenerationFailed();
                        }
                    
                        emit finished();
                    }
                    

                    Screenshot:
                    alt text

                    So, it does not freeze much for 1 page. Anyway, I want to display some progress dialog before the preview dialog. Any ideas? Thanks.

                    jsulmJ 1 Reply Last reply
                    0
                    • Cobra91151C Cobra91151

                      @jsulm @JonB

                      Here is my test example:

                      printexample.h

                      #ifndef PRINTEXAMPLE_H
                      #define PRINTEXAMPLE_H
                      
                      #include <QWidget>
                      #include <QPushButton>
                      #include <QHBoxLayout>
                      #include <QThread>
                      #include <QPrinter>
                      #include <QPrintPreviewDialog>
                      #include <QToolBar>
                      #include <QTextDocument>
                      #include <QDebug>
                      #include "printworker.h"
                      
                      class PrintExample : public QWidget
                      {
                          Q_OBJECT
                      
                      public:
                          PrintExample(QWidget *parent = nullptr);
                          ~PrintExample();
                      
                      private slots:
                          void printData();
                          void setPrintPreviewData(QString printData);
                          void setPreviewDataGenerationFailed();
                      
                      private:
                          QLayout *printLayout(QPushButton *btn);
                      };
                      #endif // PRINTEXAMPLE_H
                      

                      printexample.cpp

                      #include "printexample.h"
                      
                      PrintExample::PrintExample(QWidget *parent)
                          : QWidget(parent)
                      {
                          setWindowTitle("Print example");
                          setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
                          setFixedSize(500, 400);
                          QPushButton *printBtn = new QPushButton("Print", this);
                          printBtn->setFixedSize(120, 50);
                          connect(printBtn, &QPushButton::clicked, this, &PrintExample::printData);
                          setLayout(printLayout(printBtn));
                      }
                      
                      QLayout *PrintExample::printLayout(QPushButton *btn)
                      {
                          QHBoxLayout *btnLayout = new QHBoxLayout();
                          btnLayout->setAlignment(Qt::AlignHCenter);
                          btnLayout->addWidget(btn);
                          return btnLayout;
                      }
                      
                      void PrintExample::printData()
                      {
                          //This is just test example data
                          QString testBigData = "QTextDocument is a container for structured rich text documents, providing support for styled text and various types of document elements, such as lists, tables, "
                                                "frames, and images. They can be created for use in a QTextEdit, or used independently. Each document element is described by an associated format object. "
                                                "Each format object is treated as a unique object by QTextDocuments, and can be passed to objectForFormat() to obtain the document element that it is applied to. "
                                                "A QTextDocument can be edited programmatically using a QTextCursor, and its contents can be examined by traversing the document structure. "
                                                "The entire document structure is stored as a hierarchy of document elements beneath the root frame, found with the rootFrame() function. "
                                                "Alternatively, if you just want to iterate over the textual contents of the document you can use begin(), end(), and findBlock() to retrieve text blocks that you can "
                                                "examine and iterate over. The layout of a document is determined by the documentLayout(); you can create your own QAbstractTextDocumentLayout subclass and set it using "
                                                "setDocumentLayout() if you want to use your own layout logic. The document's title and other meta-information can be obtained by calling the metaInformation() "
                                                "function. For documents that are exposed to users through the QTextEdit class, the document title is also available via the QTextEdit::documentTitle() "
                                                "function. The toPlainText() and toHtml() convenience functions allow you to retrieve the contents of the document as plain text and HTML. "
                                                "The document's text can be searched using the find() functions. Undo/redo of operations performed on the document can be controlled using the setUndoRedoEnabled() "
                                                "function. The undo/redo system can be controlled by an editor widget through the undo() and redo() slots; the document also provides contentsChanged(), "
                                                "undoAvailable(), and redoAvailable() signals that inform connected editor widgets about the state of the undo/redo system. "
                                                "The following are the undo/redo operations of a QTextDocument.";
                          QThread *printDataThread = new QThread();
                          PrintWorker *printWorker = new PrintWorker();
                          printWorker->moveToThread(printDataThread);
                          connect(printWorker, &PrintWorker::generatedPreviewData, this, &PrintExample::setPrintPreviewData);
                          connect(printWorker, &PrintWorker::previewDataGenerationFailed, this, &PrintExample::setPreviewDataGenerationFailed);
                          connect(printWorker, &PrintWorker::finished, printDataThread, &QThread::quit);
                          connect(printWorker, &PrintWorker::finished, printWorker, &PrintWorker::deleteLater);
                          connect(printDataThread, &QThread::finished, printDataThread, &QThread::deleteLater);
                          QMetaObject::invokeMethod(printWorker, "generatePrintPreview", Q_ARG(QString, testBigData));
                          printDataThread->start();
                      }
                      
                      void PrintExample::setPrintPreviewData(QString printData)
                      {
                          QPrinter *previewPrinter = new QPrinter(QPrinter::HighResolution);
                          previewPrinter->setOutputFormat(QPrinter::NativeFormat);
                          previewPrinter->setPaperSize(QPrinter::A4);
                          previewPrinter->setPageMargins(QMarginsF(15, 15, 15, 15));
                          QPrintPreviewDialog *printPreviewDlg = new QPrintPreviewDialog(previewPrinter, this);
                          printPreviewDlg->setGeometry(100, 100, 700, 500);
                          printPreviewDlg->setMinimumSize(700, 500);
                          printPreviewDlg->setWindowModality(Qt::ApplicationModal);
                          printPreviewDlg->setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
                          printPreviewDlg->installEventFilter(this);
                          QFont docFont;
                          docFont.setPointSize(14);
                          QTextDocument *textDoc = new QTextDocument(this);
                          textDoc->setDefaultFont(docFont);
                          textDoc->setPlainText(printData);
                          connect(printPreviewDlg, &QPrintPreviewDialog::paintRequested, this, [this, textDoc](QPrinter *printer) {
                              textDoc->print(printer);
                          });
                          connect(printPreviewDlg, &QPrintPreviewDialog::finished, this, [textDoc, previewPrinter, printPreviewDlg]() {
                              textDoc->deleteLater();
                              delete previewPrinter;
                              printPreviewDlg->deleteLater();
                          });
                          printPreviewDlg->show();
                      }
                      
                      void PrintExample::setPreviewDataGenerationFailed()
                      {
                          //Failed to generate preview
                      }
                      
                      PrintExample::~PrintExample()
                      {
                      
                      }
                      

                      printworker.h:

                      #ifndef PRINTWORKER_H
                      #define PRINTWORKER_H
                      
                      #include <QObject>
                      
                      class PrintWorker : public QObject
                      {
                          Q_OBJECT
                      public:
                          explicit PrintWorker(QObject *parent = nullptr);
                      
                      public slots:
                          void generatePrintPreview(QString previewData);
                      
                      signals:
                          void generatedPreviewData(QString data);
                          void previewDataGenerationFailed();
                          void finished();
                      };
                      
                      #endif // PRINTWORKER_H
                      

                      printworker.cpp:

                      #include "printworker.h"
                      
                      PrintWorker::PrintWorker(QObject *parent) : QObject(parent)
                      {
                      
                      }
                      
                      void PrintWorker::generatePrintPreview(QString previewData)
                      {
                          if (!previewData.isEmpty()) {
                              emit generatedPreviewData(previewData);
                          } else {
                              emit previewDataGenerationFailed();
                          }
                      
                          emit finished();
                      }
                      

                      Screenshot:
                      alt text

                      So, it does not freeze much for 1 page. Anyway, I want to display some progress dialog before the preview dialog. Any ideas? Thanks.

                      jsulmJ Offline
                      jsulmJ Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #21

                      @Cobra91151 I'm not sure there is an easy way to add a progress dialog here as printing does not emit any signals reporting progress as far as I know. But you could have a busy indicator to let the user know that the app is busy. Would that be enough?

                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                      Cobra91151C 1 Reply Last reply
                      2
                      • jsulmJ jsulm

                        @Cobra91151 I'm not sure there is an easy way to add a progress dialog here as printing does not emit any signals reporting progress as far as I know. But you could have a busy indicator to let the user know that the app is busy. Would that be enough?

                        Cobra91151C Offline
                        Cobra91151C Offline
                        Cobra91151
                        wrote on last edited by
                        #22

                        @jsulm

                        Yes, it should work well too. Thanks.

                        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