Is it possible to set a header and footer when printing a QTextDocument?

There is no API for this at the moment, so you will have to implement this yourself. In order to do this manually, what needs to be done is to print the header and footer yourself and use QTextDocument::drawContents() [doc.qt.nokia.com] to draw the relevant part of the page that will fit on the paper. In order to do this you need to calculate what area of the page rectangle your header and footer will occupy and the rest is used for the content of the document. By moving the rectangle that gets what needs to be painted each time and translating the painter so that is effectively painting at 0×0 then it will paint the contents for that page as drawContents() [doc.qt.nokia.com] will clip the painting to the specified rectangle. This is put into a while loop that checks that the rectangle to be painted is actually intersecting with the complete contents rectangle.

The following is an example of how it can be implemented:

  1. #include <QtGui>
  2.  
  3. int main(int argc, char **argv)
  4. {
  5.     QApplication a(argc, argv);
  6.     QFile f("test.html");
  7.     f.open(QIODevice::ReadOnly);
  8.     QString content = f.readAll();
  9.     f.close();
  10.     QTextDocument td;
  11.     td.setHtml(content);
  12.     QPrinter p;
  13.     QPrintDialog pd(&p, 0);
  14.     pd.exec();
  15.     td.setPageSize(p.pageRect().size());
  16.     QRect innerRect = p.pageRect();
  17.     innerRect.setTop(innerRect.top() + 20);
  18.     innerRect.setBottom(innerRect.bottom() - 30);
  19.     QRect contentRect = QRect(QPoint(0,0), td.size().toSize());
  20.     QRect currentRect = QRect(QPoint(0,0), innerRect.size());
  21.     QPainter painter(&p);
  22.     int count = 0;
  23.     painter.save();
  24.     painter.translate(0, 30);
  25.     while (currentRect.intersects(contentRect)) {
  26.         td.drawContents(&painter, currentRect);
  27.         count++;
  28.         currentRect.translate(0, currentRect.height());
  29.         painter.restore();
  30.         painter.drawText(10, 10, QString("Header %1").arg(count));
  31.         painter.drawText(10, p.pageRect().bottom() - 10, QString("Footer %1").arg(count));
  32.         painter.save();
  33.         painter.translate(0, -currentRect.height() * count + 30);
  34.         if (currentRect.intersects(contentRect))
  35.             p.newPage();
  36.     }
  37.     painter.restore();
  38.     painter.end();
  39.     return 0;
  40. }
  41.  

4 comments

January 12, 2012

Picture of bmanc bmanc

Lab Rat

Thank you. This also helps with my problem – I want to print or paint different parts of the QTextDocument onto a QGraphicsView, where I control the position of the “windows” or “viewports” onto the document.

From the documentation it wasn’t clear to how the rect was clipping the document in QTextDocument::drawContent(QPainter*, const QRectF). The example definitely clarifies that.

May 2, 2012

Picture of castors33 castors33

Lab Rat

Really useful!

But I was wonderring if it is possible to change the size of the text of the header and/or the footer

August 13, 2012

Picture of zbenjamin zbenjamin

Lab Rat

It is also possible to use a toplevel QTextTable and mark the first row as a header:

  1.  
  2.     QTextTableFormat outerTableFormat;
  3.     outerTableFormat.setCellSpacing(0);
  4.     outerTableFormat.setCellPadding(0);
  5.     outerTableFormat.setBorder(0);
  6.     outerTableFormat.setHeaderRowCount(1); //this will repeat the first column
  7.     outerTableFormat.setAlignment(Qt::AlignHCenter);
  8.     outerTableFormat.setWidth(QTextLength(QTextLength::PercentageLength, 80));
  9.     QTextTable *outerTable = cursor.insertTable(2,1,outerTableFormat);

March 25, 2013

Picture of josh h josh h

Lab Rat

If the printer is set to QPrinter::HighResolution then you may need to add the following line:

  1. td.documentLayout()->setPaintDevice(&p);

just before

  1. td.setPageSize(p.pageRect().size());

so that the scaling between the text document and printer is done correctly.

Write a comment

Sorry, you must be logged in to post a comment.