На этом шаге мы приведем пример класса который можно использовать при выводе на печать.
В тексте ниже приведен код класса PrintList, реализующий печать списков или содержимого таблиц баз данных в виде полноценного табличного отчета. Этот класс можно использовать для разработки приложений.
from PyQt5 import QtCore, QtGui, QtPrintSupport class PrintList: def __init__(self) : self.printer = QtPrintSupport.QPrinter() self.headerFont = QtGui.QFont("Arial", pointSize=10, weight = QtGui.QFont.Bold) self.bodyFont = QtGui.QFont("Arial", pointSize=10) self.footerFont = QtGui.QFont("Arial", pointSize=9, italic=True) self.headerFlags = QtCore.Qt.AlignHCenter | QtCore.Qt.TextWordWrap self.bodyFlags = QtCore.Qt.TextWordWrap self.footerFlags = QtCore.Qt.AlignHCenter | QtCore.Qt.TextWordWrap color = QtGui.QColor(QtCore.Qt.black) self.headerPen = QtGui.QPen(color, 2) self.bodyPen = QtGui.QPen(color, 1) self.margin = 5 self._resetData() def _resetData(self): self.headers = None self.columnWidths = None self.data = None self._brush = QtCore.Qt.NoBrush self._currentRowHeight = 0 self._currentPageHeight = 0 self._headerRowHeight = 0 self._footerRowHeight = 0 self._currentPageNumber = 1 self._painter = None def printData(self): self._painter = QtGui.QPainter() self._painter.begin(self.printer) self._painter.setBrush(self._brush) if self._headerRowHeight == 0: self._painter.setFont(self.headerFont) self._headerRowHeight = self._calculateRowHeight(self.columnWidths, self.headers) if self._footerRowHeight == 0: self._painter.setFont(self.footerFont) self._footerRowHeight = self._calculateRowHeight([self.printer.width()], "Страница") for i in range(len(self.data)): height = self._calculateRowHeight(self.columnWidths, self.data[i]) if self._currentPageHeight + height > self.printer.height() - self._footerRowHeight - 2 * self.margin: self._printFooterRow() self._currentPageHeight = 0 self._currentPageNumber += 1 self.printer.newPage() if self._currentPageHeight == 0: self._painter.setPen(self.headerPen) self._painter.setFont(self.headerFont) self.printRow(self.columnWidths, self.headers, self._headerRowHeight, self.headerFlags) self._painter.setPen(self.bodyPen) self._painter.setFont(self.bodyFont) self.printRow(self.columnWidths, self.data[i], height, self.bodyFlags) self._printFooterRow() self._painter.end() self._resetData() def _calculateRowHeight(self, widths, cellData): height = 0 for i in range(len(widths)): r = self._painter.boundingRect(0, 0, widths[i] - 2 * self.margin, 50, QtCore.Qt.TextWordWrap, str(cellData[i])) h = r.height() + 2 * self.margin if height < h: height = h return height def printRow(self, widths, cellData, height, flags): x = 0 for i in range(len(widths)): self._painter.drawText(x + self.margin, self._currentPageHeight + self.margin, widths[i] - self.margin, height - 2 * self.margin, flags, str(cellData[i])) self._painter.drawRect(x, self._currentPageHeight, widths[i], height) x += widths[i] self._currentPageHeight += height def _printFooterRow(self): self._painter.setFont(self.footerFont) self._painter.drawText(self.margin, self.printer.height() - self._footerRowHeight - self.margin, self.printer.width() - 2 * self.margin, self._footerRowHeight - 2 * self.margin, self.footerFlags, "Страница " + str(self._currentPageNumber))
Пользоваться этим классом очень просто: сначала нужно создать его экземпляр, вызвав конструктор следующего формата:
<Объект> = PrintList()
После чего задать параметры печатаемого табличного отчета, воспользовавшись следующими атрибутами класса PrintList:
Следующие свойства являются необязательными для указания:
После задания всех необходимых параметров следует вызвать метод printData() класса PrintList, который и выполняет печать данных. Впоследствии, пользуясь тем же экземпляром этого класса, мы можем распечатать другой набор данных.
В примере ниже приведен код тестового приложения, выводящего на экран числа от 1 до 100, их квадраты и кубы. Подразумевается, что код класса, приведенный в начале этого шага, сохранен в файле PrintList.ру.
from PyQt5 import QtWidgets import sys import PrintList app = QtWidgets.QApplication(sys.argv) pl = PrintList.PrintList() # Если требуется вывести документ в файл формата PDF, # следует раскомментировать эту строку: # pl.printer.setOutputFileName("output.pdf") data = [] for b in range(1, 101): data.append([b, b ** 2, b ** 3]) pl.data = data pl.columnWidths = [100, 100, 200] pl.headers = ["Аргумент", "Квадрат", "Куб"] pl.printData()
В результате мы должны получить табличный документ из трех страниц с тремя столбцами и нумерацией в "поддоне".
Фрагмент результирующего pdf-файла изображен на рисунке 1.
Рис.1. Фрагмент вывода результата в pdf-файл
На следующем шаге мы рассмотрим служебные классы.