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. Why does it draw headers like this?
Forum Updated to NodeBB v4.3 + New Features

Why does it draw headers like this?

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

    Here's how it looks:

    x1.gif

    on the first page it's perfect. On the second page, I get a piece of overflown text from first page and after that it draws the header in between black horizontal lines. On the 3rd and 4th page those header texts are not in between lines! Is there anything wrong in the computation? Here's the code:

    Window::Window(QWidget *parent) : QWidget(parent){
        printer = new QPrinter();
        printer->setPageSize(QPageSize::A4);
        printer->setPageMargins(QMarginsF(20,20,20,20), QPageLayout::Millimeter);
        document = new QTextDocument(this);
        auto rect = printer->pageRect(QPrinter::Point).size(); // w: 481 h:728
        document->setPageSize(QSizeF(rect.width(), rect.height()));
        createDocument();
        auto preview = new QPrintPreviewWidget(printer);
        preview->setZoomMode(QPrintPreviewWidget::ZoomMode::FitToWidth);
        connect(preview, &QPrintPreviewWidget::paintRequested, [=]{document->print(printer);});
        auto lay = new QVBoxLayout(this);
        lay->addWidget(preview);
    }
    void Window::addHeader(int row, QTextCursor& cursor){
        for (int i = 0; i < 4; i++) {
            auto cell = cursor.currentTable()->cellAt(row, i);
            QTextTableCellFormat cellFormat;
            cellFormat.setTopBorder(1);
            cellFormat.setBottomBorder(1);
            cellFormat.setBorderBrush(Qt::black);
            cellFormat.setTopBorderStyle(QTextFrameFormat::BorderStyle_Solid);
            cellFormat.setBottomBorderStyle(QTextFrameFormat::BorderStyle_Solid);
            cell.setFormat(cellFormat);
            QTextCharFormat textFormat;
            textFormat.setFontWeight(QFont::Bold);
            QTextBlockFormat blockFormat;
            blockFormat.setAlignment(Qt::AlignCenter);
            cursor.setBlockFormat(blockFormat);
            cursor.insertText("Column " + QString::number(i + 1), textFormat);
            cursor.movePosition(QTextCursor::NextCell);
        }
    }
    void Window::createDocument(){
        int row = 50, column = 4;
        QTextCursor cursor(document);
        QTextTableFormat tableFormat;
        tableFormat.setBorder(0);
        tableFormat.setCellSpacing(0);
        tableFormat.setCellPadding(3);
        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);
        cursor.insertTable(1, 4, tableFormat);
        addHeader(0, cursor);
        QFontMetrics fm(font());
        // w: 481 h:728
        int heightLeft = 728 - 20; // for single line QFontMetrics says 16 and assumed each of those line in header are 2px/pt
        QRect col1Rect(0,0, 481 * 0.40, fm.boundingRect("tg").height());
        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++) {
                if(c == 0){
                    auto col1Text = "Column1 Text Column1 Text Column1 Text Column1 Text Column1 Text";
                    auto reqRect = fm.boundingRect(col1Rect, Qt::AlignLeft | Qt::TextWordWrap, col1Text);
                    heightLeft -= reqRect.height() + 6; // 6 for cell padding
                    if(heightLeft < 0){
                        heightLeft = 728 - 20;
                        addHeader(r, cursor);
                        cursor.currentTable()->appendRows(1);
                        cursor = cursor.currentTable()->rowStart(cursor);
                        cursor.movePosition(QTextCursor::NextCell);
                    }
                    else{
                        cursor.insertText(col1Text);
                        cursor.movePosition(QTextCursor::NextCell);
                        continue;
                    }
                }
                cursor.insertText("Row " + QString::number(r) + " Column " + QString::number(c));
                cursor.movePosition(QTextCursor::NextCell);
            }
        }
    }
    
    1 Reply Last reply
    0
    • D Offline
      D Offline
      deleted385
      wrote on last edited by
      #7

      Adding header is actually much simpler than what I thought. All I need is tableFormat.setHeaderRowCount(1); and add header just once and no need to calculate anything manually:

      x3.gif

      The only thing that bothers now is those horizontal lines, appears/disappears when I scroll. Here's the updated 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()); // no need if you want bigger font
          auto pageRect = printer->pageRect(QPrinter::DevicePixel).size(); // set to QPrinter::Point if you want bigger font
          document->setPageSize(QSizeF(pageRect.width(), pageRect.height()));
          //document->documentLayout()->setPaintDevice(printer);
          createDocument();
          auto preview = new QPrintPreviewWidget(printer);
          preview->setZoomMode(QPrintPreviewWidget::ZoomMode::FitToWidth);
          connect(preview, &QPrintPreviewWidget::paintRequested, [=](QPrinter *p){document->print(p);});
          auto lay = new QVBoxLayout(this);
          auto button = new QPushButton("Pint PDF", this);
          lay->addWidget(button);
          lay->addWidget(preview);
          connect(button, &QPushButton::clicked, [=]{
              printer->setOutputFormat(QPrinter::PdfFormat);
              printer->setOutputFileName("test.pdf");
              document->print(printer);
          });
      }
      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);
          QTextBlockFormat blockFormat;
          blockFormat.setAlignment(Qt::AlignCenter);
          cursor.setBlockFormat(blockFormat);
          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 = 100, 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++) {
                  if(c == 0){
                      QString col1Text;
                      if(r % 2 == 0) col1Text = "Column1 Text Column1 Text Column1 Text Column1 Text Column1 Text Column1 Text Column1 Text";
                      else col1Text = "Some other Column1 Text text text";
                      cursor.insertText(col1Text);
                      cursor.movePosition(QTextCursor::NextCell);
                      continue;
                  }
                  cursor.insertText("Row " + QString::number(r) + " Column " + QString::number(c));
                  cursor.movePosition(QTextCursor::NextCell);
              }
          }
      }
      
      1 Reply Last reply
      0
      • JoeCFDJ Offline
        JoeCFDJ Offline
        JoeCFD
        wrote on last edited by JoeCFD
        #2

        Update is too fast and you may need to slow down the scroll speed.
        setVerticalScrollMode( QAbstractItemView::ScrollPerPixel );
        and play with frame rate
        QScroller::grabGesture( your widget, QScroller::TouchGesture ); /* for touch screen in case */
        QScrollerProperties properties = QScroller::scroller( your widget )->scrollerProperties();
        properties.setScrollMetric( QScrollerProperties::FrameRate, frame_rates );

        D 1 Reply Last reply
        1
        • JoeCFDJ JoeCFD

          Update is too fast and you may need to slow down the scroll speed.
          setVerticalScrollMode( QAbstractItemView::ScrollPerPixel );
          and play with frame rate
          QScroller::grabGesture( your widget, QScroller::TouchGesture ); /* for touch screen in case */
          QScrollerProperties properties = QScroller::scroller( your widget )->scrollerProperties();
          properties.setScrollMetric( QScrollerProperties::FrameRate, frame_rates );

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

          @JoeCFD, couldn't do setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ) on any of Window (QWidget), preview (QPrintPreviewWidget) or document QTextDocument. It says no member named 'setVerticalScrollMode' in ... Tried this:

          auto properties = QScroller::scroller(/*this/preview/document*/)->scrollerProperties();
          properties.setScrollMetric( QScrollerProperties::FrameRate, /*from 10 to 60*/ );
          

          in all of those 3. same output.

          JoeCFDJ 1 Reply Last reply
          0
          • D deleted385

            @JoeCFD, couldn't do setVerticalScrollMode( QAbstractItemView::ScrollPerPixel ) on any of Window (QWidget), preview (QPrintPreviewWidget) or document QTextDocument. It says no member named 'setVerticalScrollMode' in ... Tried this:

            auto properties = QScroller::scroller(/*this/preview/document*/)->scrollerProperties();
            properties.setScrollMetric( QScrollerProperties::FrameRate, /*from 10 to 60*/ );
            

            in all of those 3. same output.

            JoeCFDJ Offline
            JoeCFDJ Offline
            JoeCFD
            wrote on last edited by
            #4

            @Emon-Haque true. There is no scroller for you to manipulate. Adding your own one? I am not familiar with this widget. It is scroll speed problem.

            D 1 Reply Last reply
            1
            • JoeCFDJ JoeCFD

              @Emon-Haque true. There is no scroller for you to manipulate. Adding your own one? I am not familiar with this widget. It is scroll speed problem.

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

              @JoeCFD, no idea about creating my own. Point and Pixel could be another reason, not sure.

              1 Reply Last reply
              0
              • D Offline
                D Offline
                deleted385
                wrote on last edited by deleted385
                #6

                With tableFormat.setPageBreakPolicy(QTextTableFormat::PageBreak_AlwaysBefore); it's slightly better, I always get header text in between lines and on a new page:

                x1.gif

                BUT it still gets wrong heightLeft. Restructured the code

                Window::Window(QWidget *parent) : QWidget(parent){
                    printer = new QPrinter();
                    printer->setPageSize(QPageSize::A4);
                    printer->setPageMargins(QMarginsF(20,20,20,20), QPageLayout::Millimeter);
                    document = new QTextDocument(this);
                    auto rect = printer->pageRect(QPrinter::Point).size(); //w:481 h:728
                    document->setPageSize(QSizeF(rect.width(), rect.height()));
                    createDocument();
                    auto preview = new QPrintPreviewWidget(printer);
                    preview->setZoomMode(QPrintPreviewWidget::ZoomMode::FitToWidth);
                    connect(preview, &QPrintPreviewWidget::paintRequested, [=]{document->print(printer);});
                    auto lay = new QVBoxLayout(this);
                    auto button = new QPushButton("Pint PDF", this);
                    lay->addWidget(button);
                    lay->addWidget(preview);
                    connect(button, &QPushButton::clicked, [=]{
                        printer->setOutputFormat(QPrinter::PdfFormat);
                        printer->setOutputFileName("test.pdf");
                        document->print(printer);
                    });
                }
                void Window::addHeader(QTextCursor& cursor){
                    for (int i = 0; i < 4; i++) {
                        auto cell = cursor.currentTable()->cellAt(0, i);
                        QTextTableCellFormat cellFormat;
                        cellFormat.setTopBorder(1);
                        cellFormat.setBottomBorder(1);
                        cellFormat.setBorderBrush(Qt::black);
                        cellFormat.setTopBorderStyle(QTextFrameFormat::BorderStyle_Solid);
                        cellFormat.setBottomBorderStyle(QTextFrameFormat::BorderStyle_Solid);
                        cell.setFormat(cellFormat);
                        QTextCharFormat textFormat;
                        textFormat.setFontWeight(QFont::Bold);
                        QTextBlockFormat blockFormat;
                        blockFormat.setAlignment(Qt::AlignCenter);
                        cursor.setBlockFormat(blockFormat);
                        cursor.insertText("Column " + QString::number(i + 1), textFormat);
                        cursor.movePosition(QTextCursor::NextCell);
                    }
                }
                QTextTableFormat Window::format(bool pageBreak = true){
                    QTextTableFormat tableFormat;
                    tableFormat.setBorder(0);
                    tableFormat.setCellSpacing(0);
                    tableFormat.setCellPadding(3);
                    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);
                    if(pageBreak) tableFormat.setPageBreakPolicy(QTextTableFormat::PageBreak_AlwaysBefore);
                    return tableFormat;
                }
                void Window::createDocument(){
                    int row = 100, column = 4;
                    QTextCursor cursor(document);
                    cursor.insertTable(1, 4, format(false));
                    addHeader(cursor);
                    QFontMetrics fm(font());
                    int cellPadding =  3 * 2;
                    int headerLineHeight = 1 * 2;
                    int headerHeight = 16 + headerLineHeight;
                    int contentHeight = 728;
                    int heightLeft = contentHeight - headerHeight - cellPadding;
                    qDebug() << heightLeft;
                    QRect col1Rect(0,0, 481 * 0.40, fm.boundingRect("tg").height());
                    for (int r = 1; r < row; r++) {
                        cursor.currentTable()->appendRows(1);
                        cursor = cursor.currentTable()->rowStart(cursor);
                        cursor.movePosition(QTextCursor::NextRow /*QTextCursor::NextCell*/);
                        for (int c = 0; c < column; c++) {
                            if(c == 0){
                                auto col1Text = "Column1 Text Column1 Text Column1 Text Column1 Text Column1 Text";
                                auto reqRect = fm.boundingRect(col1Rect, Qt::AlignLeft | Qt::TextWordWrap, col1Text);
                                heightLeft -= reqRect.height() + cellPadding;
                                if(heightLeft < 0){
                                    heightLeft = contentHeight - headerHeight - cellPadding;
                                    qDebug() << heightLeft;
                                    cursor.movePosition(QTextCursor::End);
                                    cursor.insertTable(1, 4, format());
                                    addHeader(cursor);
                                    cursor.currentTable()->appendRows(1);
                                    cursor = cursor.currentTable()->rowStart(cursor);
                                    cursor.movePosition(QTextCursor::NextRow /*QTextCursor::NextCell*/);
                                }
                                cursor.insertText(col1Text);
                                cursor.movePosition(QTextCursor::NextCell);
                                continue;
                            }
                            cursor.insertText("Row " + QString::number(r) + " Column " + QString::number(c));
                            cursor.movePosition(QTextCursor::NextCell);
                        }
                    }
                }
                

                on the second page I get 1 line and after that on every subsequent even page I get that line and a row.

                EDIT
                Very close after redefining int contentHeight = 728 - 2*document->documentMargin(); With this change from 3rd page onward, every odd page get 1 line (no row).

                EDIT
                Also tried float/double instead of int BUT the result is identical:

                void Window::createDocument(){
                    int row = 100, column = 4;
                    QTextCursor cursor(document);
                    cursor.insertTable(1, 4, format(false));
                    addHeader(cursor);
                    QFontMetricsF headerFm(QFont(font().family(), -1, QFont::Bold, false));;
                    auto header = headerFm.boundingRect("Column 1");
                    QFontMetricsF fm(font());
                    qreal cellPadding =  3 * 2;
                    qreal headerLineHeight = 1 * 2;
                    qreal headerHeight = header.height() + headerLineHeight;
                    qreal contentHeight = 728 - 2 * document->documentMargin();
                    qreal heightLeft = contentHeight - headerHeight - cellPadding;
                    QRectF col1Rect(0,0, 481 * 0.40, fm.boundingRect("tg").height());
                    ...
                }
                
                1 Reply Last reply
                0
                • D Offline
                  D Offline
                  deleted385
                  wrote on last edited by
                  #7

                  Adding header is actually much simpler than what I thought. All I need is tableFormat.setHeaderRowCount(1); and add header just once and no need to calculate anything manually:

                  x3.gif

                  The only thing that bothers now is those horizontal lines, appears/disappears when I scroll. Here's the updated 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()); // no need if you want bigger font
                      auto pageRect = printer->pageRect(QPrinter::DevicePixel).size(); // set to QPrinter::Point if you want bigger font
                      document->setPageSize(QSizeF(pageRect.width(), pageRect.height()));
                      //document->documentLayout()->setPaintDevice(printer);
                      createDocument();
                      auto preview = new QPrintPreviewWidget(printer);
                      preview->setZoomMode(QPrintPreviewWidget::ZoomMode::FitToWidth);
                      connect(preview, &QPrintPreviewWidget::paintRequested, [=](QPrinter *p){document->print(p);});
                      auto lay = new QVBoxLayout(this);
                      auto button = new QPushButton("Pint PDF", this);
                      lay->addWidget(button);
                      lay->addWidget(preview);
                      connect(button, &QPushButton::clicked, [=]{
                          printer->setOutputFormat(QPrinter::PdfFormat);
                          printer->setOutputFileName("test.pdf");
                          document->print(printer);
                      });
                  }
                  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);
                      QTextBlockFormat blockFormat;
                      blockFormat.setAlignment(Qt::AlignCenter);
                      cursor.setBlockFormat(blockFormat);
                      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 = 100, 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++) {
                              if(c == 0){
                                  QString col1Text;
                                  if(r % 2 == 0) col1Text = "Column1 Text Column1 Text Column1 Text Column1 Text Column1 Text Column1 Text Column1 Text";
                                  else col1Text = "Some other Column1 Text text text";
                                  cursor.insertText(col1Text);
                                  cursor.movePosition(QTextCursor::NextCell);
                                  continue;
                              }
                              cursor.insertText("Row " + QString::number(r) + " Column " + QString::number(c));
                              cursor.movePosition(QTextCursor::NextCell);
                          }
                      }
                  }
                  
                  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