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. How to reduce output file size and printing time?
Qt 6.11 is out! See what's new in the release blog

How to reduce output file size and printing time?

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 2 Posters 1.2k Views 2 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.
  • D Offline
    D Offline
    deleted385
    wrote on last edited by deleted385
    #1

    Tried to follow this thread for page footer and it draws page footer correctly:

    cap1.PNG

    BUT takes much longer time and produces much larger file size than necessary. Also, not sure whether I've screwed up the actual process anywhere in code! Here's the code:

    Window::Window(QWidget *parent) : QWidget(parent){
        document = new QTextDocument();
        document->setUndoRedoEnabled(false);
        printer = new QPrinter();
        printer->setPageSize(QPageSize::A4);
        printer->setPageMargins(QMarginsF(72,72,72,72), QPageLayout::Point);
        printer->setResolution(fontMetrics().fontDpi());
        auto pageRect = printer->pageRect(QPrinter::DevicePixel).size();
        document->setPageSize(QSizeF(pageRect.width(), pageRect.height()));
        createDocument();
        auto lay = new QVBoxLayout(this);
        auto button = new QPushButton("Pint PDF", this);
        lay->addWidget(button);
        connect(button, &QPushButton::clicked, [=]{
            QElapsedTimer timer;
            timer.start();
            printer->setOutputFormat(QPrinter::PdfFormat);
            printer->setOutputFileName("test.pdf");
            //document->print(printer);
            bool firstPage = true;
            int pageCount = document->pageCount();
            QRectF textRect(0, 0, pageRect.width(), pageRect.height());
            QPainter painter(printer);
            for (int pageNo = 0; pageNo < pageCount; pageNo++) {
                if (!firstPage) printer->newPage();
                const QRectF textPageRect(0, pageNo * document->pageSize().height(), document->pageSize().width(), document->pageSize().height());
                painter.save();
                painter.setClipRect(textRect);
                painter.translate(0, -textPageRect.top());
                document->drawContents(&painter);
                painter.restore();
                QRectF footerRect(0, textRect.height(), textRect.width(), fontMetrics().height());
                painter.drawLine(footerRect.left(),footerRect.top(),footerRect.right(),footerRect.top());
                painter.drawText(footerRect, Qt::AlignVCenter | Qt::AlignRight, QObject::tr("Page %1/%2").arg(pageNo+1).arg(pageCount));
                firstPage = false;
            }
            qDebug() << timer.elapsed();
        });
    }
    void Window::addHeader(QTextCursor& cursor){
        QTextTableCellFormat cellFormat;
        cellFormat.setTopBorder(1);
        cellFormat.setBottomBorder(1);
        cellFormat.setBorderBrush(Qt::black);
        cellFormat.setTopBorderStyle(QTextFrameFormat::BorderStyle_Solid);
        cellFormat.setBottomBorderStyle(QTextFrameFormat::BorderStyle_Solid);
        QTextCharFormat textFormat;
        textFormat.setFontWeight(QFont::Bold);
        for (int i = 0; i < 4; i++) {
            auto cell = cursor.currentTable()->cellAt(0, i);
            cell.setFormat(cellFormat);
            cursor.insertText("Column " + QString::number(i + 1), textFormat);
            cursor.movePosition(QTextCursor::NextCell);
        }
    }
    QTextTableFormat Window::format(){
        QTextTableFormat tableFormat;
        tableFormat.setBorder(0);
        tableFormat.setCellSpacing(0);
        tableFormat.setCellPadding(0);
        tableFormat.setHeaderRowCount(1);
        QVector<QTextLength> columnLengths;
        columnLengths.append(QTextLength(QTextLength::PercentageLength, 40));
        columnLengths.append(QTextLength(QTextLength::PercentageLength, 20));
        columnLengths.append(QTextLength(QTextLength::PercentageLength, 20));
        columnLengths.append(QTextLength(QTextLength::PercentageLength, 20));
        tableFormat.setColumnWidthConstraints(columnLengths);
        return tableFormat;
    }
    void Window::createDocument(){
        int row = 2500, column = 4;
        QTextCursor cursor(document);
        cursor.insertTable(1, 4, format());
        addHeader(cursor);
        for (int r = 1; r < row; r++) {
            cursor.currentTable()->appendRows(1);
            cursor = cursor.currentTable()->rowStart(cursor);
            cursor.movePosition(QTextCursor::NextCell);
            for (int c = 0; c < column; c++) {
                cursor.insertText("Row " + QString::number(r) + " Column " + QString::number(c));
                cursor.movePosition(QTextCursor::NextCell);
            }
        }
    }
    

    It produces 2.4MB pdf and takes ~35/40sec to print. If I uncomment //document->print(printer); in the lambda in constructor and comment out rest of the code up to qDebug() << timer.elapsed(); it takes ~5/6sec to print and produces 107KB pdf.

    artwawA 1 Reply Last reply
    0
    • D deleted385

      @artwaw, I've that painter.setClipRect(textRect);

      EDIT
      @artwaw, oh drawContent also takes clipRect in addition to painter's! With that:

      document->drawContents(&painter, QRectF(0, textPageRect.top(), textRect.width(), textRect.height()));
      

      it's ok. painter.setClipRect(textRect); isn't necessary.

      artwawA Offline
      artwawA Offline
      artwaw
      wrote on last edited by
      #4

      @Emon-Haque But have you tried to actually comment out setClipRect() and put it as a param to the drawContents()? Long shot but I don't see anything off with your code so it must be something internal to Qt rather.

      For more information please re-read.

      Kind Regards,
      Artur

      D 1 Reply Last reply
      2
      • D deleted385

        Tried to follow this thread for page footer and it draws page footer correctly:

        cap1.PNG

        BUT takes much longer time and produces much larger file size than necessary. Also, not sure whether I've screwed up the actual process anywhere in code! Here's the code:

        Window::Window(QWidget *parent) : QWidget(parent){
            document = new QTextDocument();
            document->setUndoRedoEnabled(false);
            printer = new QPrinter();
            printer->setPageSize(QPageSize::A4);
            printer->setPageMargins(QMarginsF(72,72,72,72), QPageLayout::Point);
            printer->setResolution(fontMetrics().fontDpi());
            auto pageRect = printer->pageRect(QPrinter::DevicePixel).size();
            document->setPageSize(QSizeF(pageRect.width(), pageRect.height()));
            createDocument();
            auto lay = new QVBoxLayout(this);
            auto button = new QPushButton("Pint PDF", this);
            lay->addWidget(button);
            connect(button, &QPushButton::clicked, [=]{
                QElapsedTimer timer;
                timer.start();
                printer->setOutputFormat(QPrinter::PdfFormat);
                printer->setOutputFileName("test.pdf");
                //document->print(printer);
                bool firstPage = true;
                int pageCount = document->pageCount();
                QRectF textRect(0, 0, pageRect.width(), pageRect.height());
                QPainter painter(printer);
                for (int pageNo = 0; pageNo < pageCount; pageNo++) {
                    if (!firstPage) printer->newPage();
                    const QRectF textPageRect(0, pageNo * document->pageSize().height(), document->pageSize().width(), document->pageSize().height());
                    painter.save();
                    painter.setClipRect(textRect);
                    painter.translate(0, -textPageRect.top());
                    document->drawContents(&painter);
                    painter.restore();
                    QRectF footerRect(0, textRect.height(), textRect.width(), fontMetrics().height());
                    painter.drawLine(footerRect.left(),footerRect.top(),footerRect.right(),footerRect.top());
                    painter.drawText(footerRect, Qt::AlignVCenter | Qt::AlignRight, QObject::tr("Page %1/%2").arg(pageNo+1).arg(pageCount));
                    firstPage = false;
                }
                qDebug() << timer.elapsed();
            });
        }
        void Window::addHeader(QTextCursor& cursor){
            QTextTableCellFormat cellFormat;
            cellFormat.setTopBorder(1);
            cellFormat.setBottomBorder(1);
            cellFormat.setBorderBrush(Qt::black);
            cellFormat.setTopBorderStyle(QTextFrameFormat::BorderStyle_Solid);
            cellFormat.setBottomBorderStyle(QTextFrameFormat::BorderStyle_Solid);
            QTextCharFormat textFormat;
            textFormat.setFontWeight(QFont::Bold);
            for (int i = 0; i < 4; i++) {
                auto cell = cursor.currentTable()->cellAt(0, i);
                cell.setFormat(cellFormat);
                cursor.insertText("Column " + QString::number(i + 1), textFormat);
                cursor.movePosition(QTextCursor::NextCell);
            }
        }
        QTextTableFormat Window::format(){
            QTextTableFormat tableFormat;
            tableFormat.setBorder(0);
            tableFormat.setCellSpacing(0);
            tableFormat.setCellPadding(0);
            tableFormat.setHeaderRowCount(1);
            QVector<QTextLength> columnLengths;
            columnLengths.append(QTextLength(QTextLength::PercentageLength, 40));
            columnLengths.append(QTextLength(QTextLength::PercentageLength, 20));
            columnLengths.append(QTextLength(QTextLength::PercentageLength, 20));
            columnLengths.append(QTextLength(QTextLength::PercentageLength, 20));
            tableFormat.setColumnWidthConstraints(columnLengths);
            return tableFormat;
        }
        void Window::createDocument(){
            int row = 2500, column = 4;
            QTextCursor cursor(document);
            cursor.insertTable(1, 4, format());
            addHeader(cursor);
            for (int r = 1; r < row; r++) {
                cursor.currentTable()->appendRows(1);
                cursor = cursor.currentTable()->rowStart(cursor);
                cursor.movePosition(QTextCursor::NextCell);
                for (int c = 0; c < column; c++) {
                    cursor.insertText("Row " + QString::number(r) + " Column " + QString::number(c));
                    cursor.movePosition(QTextCursor::NextCell);
                }
            }
        }
        

        It produces 2.4MB pdf and takes ~35/40sec to print. If I uncomment //document->print(printer); in the lambda in constructor and comment out rest of the code up to qDebug() << timer.elapsed(); it takes ~5/6sec to print and produces 107KB pdf.

        artwawA Offline
        artwawA Offline
        artwaw
        wrote on last edited by
        #2

        @Emon-Haque said in How to reduce output file size and printing time?:

        this thread

        In the same thread OP gives a hint: https://forum.qt.io/post/366382

        For more information please re-read.

        Kind Regards,
        Artur

        D 1 Reply Last reply
        1
        • artwawA artwaw

          @Emon-Haque said in How to reduce output file size and printing time?:

          this thread

          In the same thread OP gives a hint: https://forum.qt.io/post/366382

          D Offline
          D Offline
          deleted385
          wrote on last edited by deleted385
          #3

          @artwaw, I've that painter.setClipRect(textRect);

          EDIT
          @artwaw, oh drawContent also takes clipRect in addition to painter's! With that:

          document->drawContents(&painter, QRectF(0, textPageRect.top(), textRect.width(), textRect.height()));
          

          it's ok. painter.setClipRect(textRect); isn't necessary.

          artwawA 1 Reply Last reply
          0
          • D deleted385

            @artwaw, I've that painter.setClipRect(textRect);

            EDIT
            @artwaw, oh drawContent also takes clipRect in addition to painter's! With that:

            document->drawContents(&painter, QRectF(0, textPageRect.top(), textRect.width(), textRect.height()));
            

            it's ok. painter.setClipRect(textRect); isn't necessary.

            artwawA Offline
            artwawA Offline
            artwaw
            wrote on last edited by
            #4

            @Emon-Haque But have you tried to actually comment out setClipRect() and put it as a param to the drawContents()? Long shot but I don't see anything off with your code so it must be something internal to Qt rather.

            For more information please re-read.

            Kind Regards,
            Artur

            D 1 Reply Last reply
            2
            • artwawA artwaw

              @Emon-Haque But have you tried to actually comment out setClipRect() and put it as a param to the drawContents()? Long shot but I don't see anything off with your code so it must be something internal to Qt rather.

              D Offline
              D Offline
              deleted385
              wrote on last edited by
              #5

              @artwaw, now it's ok. See the edited part.

              1 Reply Last reply
              2

              • Login

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