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?
Forum Updated to NodeBB v4.3 + New Features

How to reduce output file size and printing time?

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 2 Posters 724 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