ээдд. Прохоренок_Н_А__Дронов_В_А_Python_3_и_PyQt_5_Разработка_приложен. Николай Прохоренок Владимир Дронов
Скачать 7.92 Mb.
|
Глава 29. Печать документов 707 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 : headers — заголовки для столбцов табличного отчета в виде списка строк; columnWidths — значения ширины для столбцов, измеряемые в пикселах, в виде списка целочисленных величин; data — собственно выводимые данные. Они должны представлять собой список значе- ний, выводимых в отдельных ячейках, — каждый из элементов этого списка задает дан- ные для одной строки. Следующие свойства являются необязательными для указания: printer — задает принтер (ссылку на экземпляр класса QPrinter ), через который отчет выводится на печать. Изначально хранит принтер, используемый по умолчанию; headerFont — шрифт, используемый для вывода текста «шапки» табличного отчета. По умолчанию — полужирный шрифт Arial размером 10 пунктов; headerPen — параметры рамки, рисуемой вокруг ячеек «шапки». По умолчанию — чер- ная линия толщиной 2 пиксела; headerFlags — параметры вывода текста ячеек «шапки». По умолчанию — выравнива- ние по центру и перенос по словам; bodyFont — шрифт, используемый для вывода текста обычных строк. По умолчанию — шрифт Arial размером 10 пунктов; bodyPen — параметры рамки, рисуемой вокруг ячеек обычных строк. По умолчанию — черная линия толщиной 1 пиксел; bodyFlags — параметры вывода текста ячеек обычных строк. По умолчанию — перенос по словам; footerFont — шрифт, используемый для вывода текста «поддона» таблицы. По умолча- нию — курсивный шрифт Arial размером 9 пунктов; footerFlags — параметры вывода текста «поддона». По умолчанию — выравнивание по центру и перенос по словам; 708 Часть II. Библиотека PyQt 5 margin — величина просвета между рамкой ячейки и ее содержимым. По умолчанию — 5 пикселов. После задания всех необходимых параметров следует вызвать метод printData() класса PrintList , который и выполняет печать данных. Впоследствии, пользуясь тем же экземпля- ром этого класса, мы можем распечатать другой набор данных. В листинге 29.3 приведен код тестового приложения, выводящего на экран числа от 1 до 100, их квадраты и кубы. Подразумевается, что код, приведенный в листинге 29.2, со- хранен в файле PrintList.py Листинг 29.3. Тестовое приложение для проверки класса 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() В результате мы должны получить табличный документ из трех страниц с тремя столбцами и нумерацией в «поддоне». 29.1.3. Служебные классы PyQt 5 предоставляет нам два служебных класса, позволяющих описать параметры исполь- зуемой для печати бумаги, величины отступов от края страницы или же все это сразу. 29.1.3.1. Класс QPageSize Класс QPageSize , объявленный в модуле QtGui , описывает размеры, или, говоря другими словами, формат бумаги, на которой осуществляется печать. Для указания размера бумаги, который будет использовать принтер, предназначен метод setPageSize() класса QPrinter Форматы конструкторов класса: <Объект> = QPageSize() <Объект> = QPageSize(<Идентификатор размера бумаги>) <Объект> = QPageSize( <Объект> = QPageSize( <Объект> = QPageSize( Глава 29. Печать документов 709 Первый формат создает «пустой» экземпляр класса, не хранящий данные ни о каком разме- ре бумаги. Второй формат позволяет указать размер сразу, в виде значения одного из следующих ат- рибутов класса QPageSize (здесь приведены только наиболее употребительные размеры — полный их список можно найти на странице https://doc.qt.io/qt-5/qpagesize.html# PageSizeId-enum ): A0 ( 5 ), A1 ( 6 ), A2 ( 7 ), A3 ( 8 ), A4 ( 0 ), A5 ( 9 ), Letter ( 2 ), Legal ( 3 ). Третий и четвертый форматы служат для создания нестандартных размеров бумаги, при этом третий формат принимает в качестве первого параметра экземпляр класса QSize (см. разд. 18.5.2), указывающий сами размеры в пунктах. В параметре name можно задать имя создаваемого размера бумаги — если он не указан, будет создано имя по умолчанию вида Custom (<Ширина> x <Высота>) Если заданные размеры близки к размерам какого-либо из стандартных форматов бумаги, будет использован этот формат. В параметре matchPolicy можно задать режим подбора стандартного формата бумаги в виде одного из следующих атрибутов класса QPageSize : FuzzyMatch — 0 — размеры стандартного формата должны быть близки к заданным в конструкторе размерам в определенных рамках с учетом ориентации; FuzzyOrientationMatch — 1 — размеры стандартного формата должны быть близки к заданным в конструкторе размерам в определенных рамках без учета ориентации; ExactMatch — 2 — размеры стандартного формата должны точно совпадать с заданными в конструкторе. Четвертый формат принимает в качестве первого параметра экземпляр класса QSizeF , ука- зывающий размеры бумаги. Вторым параметром должна быть задана единица измерения размеров в виде значения одного из следующих атрибутов класса QPageSize : • Millimeter — 0 — миллиметры; • Point — 1 — пункты; • Inch — 2 — дюймы; • Pica — 3 — пики; • Didot — 4 — дидо (0,375 мм); • Cicero — 5 — цицеро (4,5 мм). Последний формат позволяет создать копию указанного в параметре экземпляра класса QPageSize Примеры: # Задаем размер бумаги A5 ps = QtGui.QPageSize(QtGui.QPageSize.A5) printer.setPageSize(ps) # Задаем размер бумаги 100 х 100 пунктов с названием "Особый размер" sz = QtCore.QSize(400, 300) ps = QtGui.QPageSize(sz, name="Особый размер", matchPolicy=QtGui.QPageSize.FuzzyMatch) pl.printer.setPageSize(ps) Класс QPageSize поддерживает следующие полезные для нас методы (полный их список можно найти на странице https://doc.qt.io/qt-5/qpagesize.html): 710 Часть II. Библиотека PyQt 5 size(<Единица измерения>) и rect(<Единица измерения>) — возвращают размеры бума- ги в заданных единицах измерения в виде экземпляра класса QSizeF или QRectF соответ- ственно; size(<Идентификатор размера бумаги>, <Единица измерения>) — возвращает размеры бумаги для заданного идентификатора формата в заданных единицах измерения, пред- ставленные экземпляром класса QSizeF : s = QtGui.QPageSize.size(QtGui.QPageSize.A0, QtGui.QPageSize.Millimeter) print(s.width(), "x", s.height()) Выведет: 841.0 x 1189.0 Метод является статическим; sizePixels(<Разрешение>) и rectPixels(<Разрешение>) — возвращают размеры бумаги в пикселах для заданного разрешения, которое измеряется в точках на дюйм. Результат представляет собой экземпляр класса QSize или QRect соответственно: ps = QtGui.QPageSize(QtGui.QPageSize.A5) s = ps.sizePixels(600) print(s.width(), "x", s.height()) Выведет: 3500 x 4958 sizePixels(<Идентификатор размера бумаги>, <Разрешение>) — возвращает размеры бумаги в пикселах для заданных идентификатора формата и разрешения, которое изме- ряется в точках на дюйм. Результат представляет собой экземпляр класса QSize . Метод является статическим; sizePoints() и rectPoints() — возвращают размеры бумаги в пунктах в виде экземпля- ра класса QSize или QRect соответственно; sizePoints(<Идентификатор размера бумаги>) — возвращает размеры бумаги в пунктах для заданного идентификатора размера в виде экземпляра класса QSize . Метод является статическим; swap( — меняет размер бумаги, хранящийся в текущем экземпляре класса, на заданный в параметре; name() — возвращает имя формата бумаги; name(<Идентификатор размера бумаги>) — возвращает имя формата бумаги, заданного идентификатором. Метод является статическим; isEquivalentTo( — возвращает True , если размеры текущего формата бу- маги равны размерам формата, переданного в параметре, и False — в противном случае. Также класс QPageSize поддерживает операторы сравнения == и != : s1 = QtGui.QPageSize(QtGui.QPageSize.A4) s2 = QtGui.QPageSize(QtGui.QPageSize.A4) s3 = QtGui.QPageSize(QtGui.QPageSize.A3) print(s1 == s2) # Выведет: True print(s1 != s3) # Выведет: True 29.1.3.2. Класс QPageLayout Класс QPageLayout , также объявленный в модуле QtGui , представляет сразу размеры, ориен- тацию страницы и величины отступов от краев страницы. Передать все эти сведения прин- теру позволяет метод setPageLayout() класса QPrinter Глава 29. Печать документов 711 Форматы вызова конструктора этого класса: <Объект> = QPageLayout() <Объект> = QPageLayout( <Объект> = QPageLayout( Первый формат создает «пустой» объект, не хранящий никаких сведений. Второй формат позволяет задать сразу все необходимые сведения о бумаге. Назначение его параметров: размер бумаги в виде экземпляра класса QPageSize ; ориентация бумаги в виде значения атрибута Portrait ( 0 , портретная) или Landscape ( 1 , ландшафтная) класса QPageLayout ; размеры отступов от краев страницы в виде экземпляра класса QMarginsF ; units — единицы измерения размеров в виде значения одного из атрибутов класса QPageLayout (они были приведены в описании метода setPageMargins() — см. разд. 29.1.1); minMargins — минимальные отступы от краев страницы, которые может соблюсти прин- тер, в виде экземпляра класса QMarginsF : layout = QtGui.QPageLayout(QtGui.QPageSize(QtGui.QPageSize.A5), QtGui.QPageLayout.Landscape, QtCore.QMarginsF(10, 10, 10, 10), units = QtGui.QPageLayout.Millimeter) pl.printer.setPageLayout(layout) Третий формат создает копию переданного в качестве параметра экземпляра класса QPageLayout Наиболее полезные для нас методы, поддерживаемые классом QPageLayout , приведены далее (полный их список можно найти на странице https://doc.qt.io/qt-5/qpagelayout.html). setPageSize( — задает размеры бу- маги в виде экземпляра класса QPageSize . В необязательном параметре minMargins мож- но указать минимальные величины отступов от краев страницы (экземпляр класса QMarginsF ); setOrientation(<Ориентация>) — задает ориентацию страницы в виде значения атрибута Portrait ( 0 , портретная) или Landscape ( 1 , ландшафтная) класса QPageLayout ; setMargins( — задает величины отступов от краев страницы в виде экземп- ляра класса QMarginsF . Возвращает True , если операция прошла успешно, и False — в противном случае; setLeftMargin(<Отступ>) , setTopMargin(<Отступ>) , setRightMargin(<Отступ>) и setBottomMargin(<Отступ>) — задают величины отступов от левого, верхнего, правого и нижнего края страницы соответственно. Возвращают True , если операция прошла успешно, и False — в противном случае; setUnits(<Единица измерения>) — задает единицу измерения размеров в виде значения одного из атрибутов класса QPageLayout (они были приведены в описании метода setPageMargins() — см. разд. 29.1.1); setMinimumMargins( — задает минимальные величины отступов от краев страницы в виде экземпляра класса QMarginsF ; 712 Часть II. Библиотека PyQt 5 swap( — меняет параметры бумаги, хранящиеся в текущем экземпляре класса, на заданные в параметре; fullRect([<Единица измерения>]) — возвращает размеры страницы с учетом ориента- ции, но без учета отступов в виде экземпляра класса QRectF . Если единица измерения не указана, выведенные значения будут исчисляться в текущей единице измерения, задан- ной в конструкторе: layout = QtGui.QPageLayout(QtGui.QPageSize(QtGui.QPageSize.A5), QtGui.QPageLayout.Landscape, QtCore.QMarginsF(10, 10, 10, 10), units = QtGui.QPageLayout.Millimeter) r = layout.fullRect() print(r.width(), "x", r.height()) Выведет: 210.0 x 148.0 fullRectPixels(<Разрешение>) — возвращает размеры страницы в пикселах с учетом ориентации, но без учета отступов для заданного разрешения, которое измеряется в точ- ках на дюйм. Результат представляет собой экземпляр класса QRect ; fullRectPoints() — возвращает размеры страницы в пунктах с учетом ориентации, но без учета отступов в виде экземпляра класса QRect ; paintRect([<Единица измерения>]) — возвращает размеры страницы с учетом ориента- ции и отступов (фактически — доступной для вывода графики области страницы) в виде экземпляра класса QRectF . Если единица измерения не указана, выведенные значения будут исчисляться в текущей единице измерения, заданной в конструкторе; paintRectPixels(<Разрешение>) — возвращает размеры страницы в пикселах с учетом ориентации и отступов для заданного разрешения, которое измеряется в точках на дюйм. Результат представляет собой экземпляр класса QRect ; paintRectPoints() — возвращает размеры страницы в пунктах с учетом ориентации и отступов в виде экземпляра класса QRect Класс QPageLayout также поддерживает операторы сравнения == и != 29.2. Задание параметров принтера и страницы Все профессионально выполненные приложения предоставляют пользователю возможность указать параметры принтера (выбрать собственно принтер из установленных в системе, за- дать число копий печатаемого документа и пр.) и страницы (указать размер бумаги, ориен- тацию и др.). Сейчас мы выясним, как это делается средствами PyQt 5. 29.2.1. Класс QPrintDialog Класс QPrintDialog реализует функциональность стандартного диалогового окна выбора и настройки принтера, которое позволяет выбрать принтер, задать количество копий, диапа- зон печатаемых страниц и некоторые другие параметры (рис. 29.1). Иерархия наследования этого класса: (QObject, QPaintDevice) — QWidget — QDialog – QAbstractPrintDialog – QPrintDialog Конструктор класса QPrintDialog имеет следующий формат: <Объект> = QPrintDialog( Глава 29. Печать документов 713 Рис. 29.1. Стандартное диалоговое окно выбора и настройки принтера В первом параметре указывается принтер, настройки которого будут задаваться в диалого- вом окне. Необязательный параметр parent может быть использован для задания родителя. Перед выводом диалогового окна настройки принтера можно указать для него значения по умолчанию, воспользовавшись методами класса QPrinter , описанными в разд. 29.1.1. На- пример, для указания размера бумаги следует вызвать метод setPageSize() , для задания количества копий — setCopyCount() и т. д. Вывести диалоговое окно на экран можно вызовом методов exec() или exec_() , унаследо- ванных от класса QDialog После закрытия диалогового окна все заданные в нем параметры при необходимости могут быть получены через соответствующие методы класса QPrinter . Так, выяснить размер бумаги, ее ориентацию и отступы от краев позволит метод pageLayout() , количество копий документа — метод copyCount() и т. д. Все эти методы были описаны в разд. 29.1.1. Впрочем, надо сказать, что все настройки, заданные в этом диалоговом окне, будут приме- нены к принтеру самой библиотекой PyQt. Так, если пользователь выберет другой принтер, печать будет выполнена на выбранном им принтере. А если он укажет напечатать документ в нескольких копиях, все эти копии будут напечатаны PyQt самостоятельно. Никакого кода нам самим для этого писать не придется. Класс QPrintDialog поддерживает следующие основные методы (полный их список можно найти на страницах https://doc.qt.io/qt-5/qabstractprintdialog.html и https://doc.qt.io/qt- 5/qprintdialog.html ): setOption(<Настройка принтера>[, on=True]) — активизирует указанную в первом па- раметре настройку принтера, если в параметре on задано значение True , и сбрасывает, если передано False . В первом параметре указывается одно из значений следующих атрибутов класса QAbstractPrintDialog или их комбинация через оператор | : 714 Часть II. Библиотека PyQt 5 • None — 0 — все настройки принтера сброшены; • PrintToFile — 1 — печать в файл; • PrintSelection — 2 — выбор принтера; • PrintPageRange — 4 — указание диапазона печатаемых страниц; • PrintShowPageSize — 8 — указание размера страницы; |