Putting ink to paper

The following is a very simplistic way of dumping text onto paper. We merely run through all lines in the active view and dump them on paper. If a line is too long for the chosen paper-size, we'll just let it run of the paper, we won't implement word-wrap.

    def slotFilePrint(self):
        margin = 10
        pageNo = 1

        if self.printer.setup(self):
            self.statusBar().message('Printing...')

            view = self.workspace.activeWindow()
            p = QPainter(self.printer)

            p.setFont(QFont("courier", 10))

            y = 0
            fm = p.fontMetrics()
            metrics = QPaintDeviceMetrics(self.printer)

            for i in range(view.numLines()):
                if margin + y > metrics.height() - margin:
                    pageNo = pageNo + 1
                    self.printer.newPage()
                    y = 0

                p.drawText(margin,
                           margin + y,
                           metrics.width(),
                           fm.lineSpacing(),
                           Qt.ExpandTabs | Qt.DontClip,
                           view.textLine(i))
                y = y + fm.lineSpacing()


            self.statusBar().message('Printing completed',2000)
        else:
            self.statusBar().message('Printing aborted',2000)
    

You can see how printing text works. A QPrinter object is a paint device, so we create a QPainter for it.

Printing requires choosing a font. In all probability, the user's screen font is not suitable for printing. For instance, many people read text on screen in 12 or 14 point fonts, but prefer printing with 10 point fonts. In the preceding code, a ten-point courier is chosen, though ideally you would want the choice of printing font to be part of the application settings.

Once the font is set, we can use QPainter.fontMetrics() to retrieve the height that each line will take on the paper. If the top margin (margin) plus the current line position (y) is greater than the height of the page, it's time for a new page. The page height is retrieved with metrics.height() which uses QPaintDeviceMetrics to provide this kind of practical information.

Actually printing each line is no different from painting text with a QPainter on a QPaintDevice. The drawText() paints the text on the device. You have to compute the x and y position, width and height of the area covered by the text to determine where exactly the text is printed.

These are Qt.AlignmentFlags, so you can mix and match AlignLeft, AlignRight, AlignHCenter, AlignTop, AlignBottom, AlignVCenter, AlignCenter, SingleLine, DontClip, ExpandTabs, ShowPrefix, WordBreak. In this case, ExpandTabs is used to make sure any tabs in the text are neatly printed, and DontClip is used to prevent errors when a line is too long for the page.