DDR爱好者之家 Design By 杰米
本文通过Python3+PyQt5实现《python Qt Gui 快速编程》这本书13章文档打印功能。本文共通过三种方式:
1、使用HTML和QTextDOcument打印文档
2、使用QTextCusor和QTextDocument打印文档
3、使用QPainter打印文档
使用Qpainter打印文档比QTextDocument需要更操心和复杂的计算,但是QPainter确实能够对输出赋予完全控制。
#!/usr/bin/env python3
import math
import sys
import html
from PyQt5.QtPrintSupport import QPrinter,QPrintDialog
from PyQt5.QtCore import (QDate, QRectF, Qt)
from PyQt5.QtWidgets import (QApplication,QDialog,
QHBoxLayout,QPushButton, QTableWidget, QTableWidgetItem,QVBoxLayout)
from PyQt5.QtGui import (QFont,QFontMetrics,QPainter,QTextCharFormat,
QTextCursor, QTextDocument, QTextFormat,
QTextOption, QTextTableFormat,
QPixmap,QTextBlockFormat)
import qrc_resources
from PyQt5.QtPrintSupport import QPrinter,QPrintDialog
from PyQt5.QtCore import (QDate, QRectF, Qt)
from PyQt5.QtWidgets import (QApplication,QDialog,
QHBoxLayout,QPushButton, QTableWidget, QTableWidgetItem,QVBoxLayout)
from PyQt5.QtGui import (QFont,QFontMetrics,QPainter,QTextCharFormat,
QTextCursor, QTextDocument, QTextFormat,
QTextOption, QTextTableFormat,
QPixmap,QTextBlockFormat)
import qrc_resources
DATE_FORMAT = "MMM d, yyyy"
class Statement(object):
def __init__(self, company, contact, address):
self.company = company
self.contact = contact
self.address = address
self.transactions = [] # List of (QDate, float) two-tuples
def balance(self):
return sum([amount for date, amount in self.transactions])
class Form(QDialog):
def __init__(self, parent=None):
super(Form, self).__init__(parent)
self.printer = QPrinter()
self.printer.setPageSize(QPrinter.Letter)
self.generateFakeStatements()
self.table = QTableWidget()
self.populateTable()
cursorButton = QPushButton("Print via Q&Cursor")
htmlButton = QPushButton("Print via &HTML")
painterButton = QPushButton("Print via Q&Painter")
quitButton = QPushButton("&Quit")
buttonLayout = QHBoxLayout()
buttonLayout.addWidget(cursorButton)
buttonLayout.addWidget(htmlButton)
buttonLayout.addWidget(painterButton)
buttonLayout.addStretch()
buttonLayout.addWidget(quitButton)
layout = QVBoxLayout()
layout.addWidget(self.table)
layout.addLayout(buttonLayout)
self.setLayout(layout)
cursorButton.clicked.connect(self.printViaQCursor)
htmlButton.clicked.connect(self.printViaHtml)
painterButton.clicked.connect(self.printViaQPainter)
quitButton.clicked.connect(self.accept)
self.setWindowTitle("Printing")
def generateFakeStatements(self):
self.statements = []
statement = Statement("Consality", "Ms S. Royal",
"234 Rue Saint Hyacinthe, 750201, Paris")
statement.transactions.append((QDate(2007, 8, 11), 2342))
statement.transactions.append((QDate(2007, 9, 10), 2342))
statement.transactions.append((QDate(2007, 10, 9), 2352))
statement.transactions.append((QDate(2007, 10, 17), -1500))
statement.transactions.append((QDate(2007, 11, 12), 2352))
statement.transactions.append((QDate(2007, 12, 10), 2352))
statement.transactions.append((QDate(2007, 12, 20), -7500))
statement.transactions.append((QDate(2007, 12, 20), 250))
statement.transactions.append((QDate(2008, 1, 10), 2362))
self.statements.append(statement)
statement = Statement("Demamitur Plc", "Mr G. Brown",
"14 Tall Towers, Tower Hamlets, London, WC1 3BX")
statement.transactions.append((QDate(2007, 5, 21), 871))
statement.transactions.append((QDate(2007, 6, 20), 542))
statement.transactions.append((QDate(2007, 7, 20), 1123))
statement.transactions.append((QDate(2007, 7, 20), -1928))
statement.transactions.append((QDate(2007, 8, 13), -214))
statement.transactions.append((QDate(2007, 9, 15), -3924))
statement.transactions.append((QDate(2007, 9, 15), 2712))
statement.transactions.append((QDate(2007, 9, 15), -273))
#statement.transactions.append((QDate(2007, 11, 8), -728))
#statement.transactions.append((QDate(2008, 2, 7), 228))
#statement.transactions.append((QDate(2008, 3, 13), -508))
#statement.transactions.append((QDate(2008, 3, 22), -2481))
#statement.transactions.append((QDate(2008, 4, 5), 195))
self.statements.append(statement)
def populateTable(self):
headers = ["Company", "Contact", "Address", "Balance"]
self.table.setColumnCount(len(headers))
self.table.setHorizontalHeaderLabels(headers)
self.table.setRowCount(len(self.statements))
for row, statement in enumerate(self.statements):
self.table.setItem(row, 0, QTableWidgetItem(statement.company))
self.table.setItem(row, 1, QTableWidgetItem(statement.contact))
self.table.setItem(row, 2, QTableWidgetItem(statement.address))
item = QTableWidgetItem("$ {0:,.2f}".format(float(statement.balance())))
item.setTextAlignment(Qt.AlignRight|Qt.AlignVCenter)
self.table.setItem(row, 3, item)
self.table.resizeColumnsToContents()
def printViaHtml(self):
htmltext = ""
for statement in self.statements:
date = QDate.currentDate().toString(DATE_FORMAT)
address = html.escape(statement.address).replace(
",", "<br>")
contact = html.escape(statement.contact)
balance = statement.balance()
htmltext += ("<p align=right><img src=':/logo.png'></p>"
"<p align=right>Greasy Hands Ltd."
"<br>New Lombard Street"
"<br>London<br>WC13 4PX<br>{0}</p>"
"<p>{1}</p><p>Dear {2},</p>"
"<p>The balance of your account is $ {3:,.2f}.").format(
date, address, contact, float(balance))
if balance < 0:
htmltext += (" <p><font color=red><b>Please remit the "
"amount owing immediately.</b></font>")
else:
htmltext += (" We are delighted to have done business "
"with you.")
htmltext += ("</p><p> </p><p>"
"<table border=1 cellpadding=2 "
"cellspacing=2><tr><td colspan=3>"
"Transactions</td></tr>")
for date, amount in statement.transactions:
color, status = "black", "Credit"
if amount < 0:
color, status = "red", "Debit"
htmltext += ("<tr><td align=right>{0}</td>"
"<td>{1}</td><td align=right>"
"<font color={2}>$ {3:,.2f}</font></td></tr>".format(
date.toString(DATE_FORMAT), status, color,float(abs(amount))))
htmltext += ("</table></p><p style='page-break-after:always;'>"
"We hope to continue doing "
"business with you,<br>Yours sincerely,"
"<br><br>K. Longrey, Manager</p>")
dialog = QPrintDialog(self.printer, self)
if dialog.exec_():
document = QTextDocument()
document.setHtml(htmltext)
document.print_(self.printer)
def printViaQCursor(self):
dialog = QPrintDialog(self.printer, self)
if not dialog.exec_():
return
logo = QPixmap(":/logo.png")
headFormat = QTextBlockFormat()
headFormat.setAlignment(Qt.AlignLeft)
headFormat.setTextIndent(
self.printer.pageRect().width() - logo.width() - 216)
bodyFormat = QTextBlockFormat()
bodyFormat.setAlignment(Qt.AlignJustify)
lastParaBodyFormat = QTextBlockFormat(bodyFormat)
lastParaBodyFormat.setPageBreakPolicy(
QTextFormat.PageBreak_AlwaysAfter)
rightBodyFormat = QTextBlockFormat()
rightBodyFormat.setAlignment(Qt.AlignRight)
headCharFormat = QTextCharFormat()
headCharFormat.setFont(QFont("Helvetica", 10))
bodyCharFormat = QTextCharFormat()
bodyCharFormat.setFont(QFont("Times", 11))
redBodyCharFormat = QTextCharFormat(bodyCharFormat)
redBodyCharFormat.setForeground(Qt.red)
tableFormat = QTextTableFormat()
tableFormat.setBorder(1)
tableFormat.setCellPadding(2)
document = QTextDocument()
cursor = QTextCursor(document)
mainFrame = cursor.currentFrame()
page = 1
for statement in self.statements:
cursor.insertBlock(headFormat, headCharFormat)
cursor.insertImage(":/logo.png")
for text in ("Greasy Hands Ltd.", "New Lombard Street",
"London", "WC13 4PX",
QDate.currentDate().toString(DATE_FORMAT)):
cursor.insertBlock(headFormat, headCharFormat)
cursor.insertText(text)
for line in statement.address.split(", "):
cursor.insertBlock(bodyFormat, bodyCharFormat)
cursor.insertText(line)
cursor.insertBlock(bodyFormat)
cursor.insertBlock(bodyFormat, bodyCharFormat)
cursor.insertText("Dear {0},".format(statement.contact))
cursor.insertBlock(bodyFormat)
cursor.insertBlock(bodyFormat, bodyCharFormat)
balance = statement.balance()
cursor.insertText("The balance of your account is $ {0:,.2f}.".format(float(balance)))
if balance < 0:
cursor.insertBlock(bodyFormat, redBodyCharFormat)
cursor.insertText("Please remit the amount owing "
"immediately.")
else:
cursor.insertBlock(bodyFormat, bodyCharFormat)
cursor.insertText("We are delighted to have done "
"business with you.")
cursor.insertBlock(bodyFormat, bodyCharFormat)
cursor.insertText("Transactions:")
table = cursor.insertTable(len(statement.transactions), 3,
tableFormat)
row = 0
for date, amount in statement.transactions:
cellCursor = table.cellAt(row, 0).firstCursorPosition()
cellCursor.setBlockFormat(rightBodyFormat)
cellCursor.insertText(date.toString(DATE_FORMAT),
bodyCharFormat)
cellCursor = table.cellAt(row, 1).firstCursorPosition()
if amount > 0:
cellCursor.insertText("Credit", bodyCharFormat)
else:
cellCursor.insertText("Debit", bodyCharFormat)
cellCursor = table.cellAt(row, 2).firstCursorPosition()
cellCursor.setBlockFormat(rightBodyFormat)
format = bodyCharFormat
if amount < 0:
format = redBodyCharFormat
cellCursor.insertText("$ {0:,.2f}".format(float(amount)), format)
row += 1
cursor.setPosition(mainFrame.lastPosition())
cursor.insertBlock(bodyFormat, bodyCharFormat)
cursor.insertText("We hope to continue doing business "
"with you,")
cursor.insertBlock(bodyFormat, bodyCharFormat)
cursor.insertText("Yours sincerely")
cursor.insertBlock(bodyFormat)
if page == len(self.statements):
cursor.insertBlock(bodyFormat, bodyCharFormat)
else:
cursor.insertBlock(lastParaBodyFormat, bodyCharFormat)
cursor.insertText("K. Longrey, Manager")
page += 1
document.print_(self.printer)
def printViaQPainter(self):
dialog = QPrintDialog(self.printer, self)
if not dialog.exec_():
return
LeftMargin = 72
sansFont = QFont("Helvetica", 10)
sansLineHeight = QFontMetrics(sansFont).height()
serifFont = QFont("Times", 11)
fm = QFontMetrics(serifFont)
DateWidth = fm.width(" September 99, 2999 ")
CreditWidth = fm.width(" Credit ")
AmountWidth = fm.width(" W999999.99 ")
serifLineHeight = fm.height()
logo = QPixmap(":/logo.png")
painter = QPainter(self.printer)
pageRect = self.printer.pageRect()
page = 1
for statement in self.statements:
painter.save()
y = 0
x = pageRect.width() - logo.width() - LeftMargin
painter.drawPixmap(x, 0, logo)
y += logo.height() + sansLineHeight
painter.setFont(sansFont)
painter.drawText(x, y, "Greasy Hands Ltd.")
y += sansLineHeight
painter.drawText(x, y, "New Lombard Street")
y += sansLineHeight
painter.drawText(x, y, "London")
y += sansLineHeight
painter.drawText(x, y, "WC13 4PX")
y += sansLineHeight
painter.drawText(x, y,
QDate.currentDate().toString(DATE_FORMAT))
y += sansLineHeight
painter.setFont(serifFont)
x = LeftMargin
for line in statement.address.split(", "):
painter.drawText(x, y, line)
y += serifLineHeight
y += serifLineHeight
painter.drawText(x, y, "Dear {0},".format(statement.contact))
y += serifLineHeight
balance = statement.balance()
painter.drawText(x, y, "The balance of your account is $ {0:,.2f}".format(float(balance)))
y += serifLineHeight
if balance < 0:
painter.setPen(Qt.red)
text = "Please remit the amount owing immediately."
else:
text = ("We are delighted to have done business "
"with you.")
painter.drawText(x, y, text)
painter.setPen(Qt.black)
y += int(serifLineHeight * 1.5)
painter.drawText(x, y, "Transactions:")
y += serifLineHeight
option = QTextOption(Qt.AlignRight|Qt.AlignVCenter)
for date, amount in statement.transactions:
x = LeftMargin
h = int(fm.height() * 1.3)
painter.drawRect(x, y, DateWidth, h)
painter.drawText(
QRectF(x + 3, y + 3, DateWidth - 6, h - 6),
date.toString(DATE_FORMAT), option)
x += DateWidth
painter.drawRect(x, y, CreditWidth, h)
text = "Credit"
if amount < 0:
text = "Debit"
painter.drawText(
QRectF(x + 3, y + 3, CreditWidth - 6, h - 6),
text, option)
x += CreditWidth
painter.drawRect(x, y, AmountWidth, h)
if amount < 0:
painter.setPen(Qt.red)
painter.drawText(
QRectF(x + 3, y + 3, AmountWidth - 6, h - 6),
"$ {0:,.2f}".format(float(amount)),
option)
painter.setPen(Qt.black)
y += h
y += serifLineHeight
x = LeftMargin
painter.drawText(x, y, "We hope to continue doing "
"business with you,")
y += serifLineHeight
painter.drawText(x, y, "Yours sincerely")
y += serifLineHeight * 3
painter.drawText(x, y, "K. Longrey, Manager")
x = LeftMargin
y = pageRect.height() - 72
painter.drawLine(x, y, pageRect.width() - LeftMargin, y)
y += 2
font = QFont("Helvetica", 9)
font.setItalic(True)
painter.setFont(font)
option = QTextOption(Qt.AlignCenter)
option.setWrapMode(QTextOption.WordWrap)
painter.drawText(
QRectF(x, y, pageRect.width() - 2 * LeftMargin, 31),
"The contents of this letter are for information "
"only and do not form part of any contract.",
option)
page += 1
if page <= len(self.statements):
self.printer.newPage()
painter.restore()
if __name__ == "__main__":
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
运行结果:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
DDR爱好者之家 Design By 杰米
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
DDR爱好者之家 Design By 杰米
暂无评论...
RTX 5090要首发 性能要翻倍!三星展示GDDR7显存
三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。
首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。
据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。
更新日志
2025年10月25日
2025年10月25日
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]
