Home Backend Development Python Tutorial python3+PyQt5 implements document printing function

python3+PyQt5 implements document printing function

Apr 24, 2018 am 11:40 AM
Function Print

This article mainly introduces the document printing function of python3 PyQt5 in detail. It has certain reference value. Interested friends can refer to it.

This article adopts Python3 PyQt5 Implement the document printing function in Chapter 13 of the book "python Qt Gui Rapid Programming". This article uses three methods:

1. Use HTML and QTextDOcument to print documents
2. Use QTextCusor and QTextDocument to print documents
3. Use QPainter to print documents

Using Qpainter to print documents requires more care and complex calculations than QTextDocument, but QPainter does give full control over the output.

#!/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=&#39;:/logo.png&#39;></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=&#39;page-break-after:always;&#39;>"
   "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_()
Copy after login

Run results:

##Related recommendations:


python3 PyQt5 implements a page indexer application that supports multi-threading

python3 PyQt5 generic delegate detailed explanation

The above is the detailed content of python3+PyQt5 implements document printing function. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

What should I do if the frame line disappears when printing in Excel? What should I do if the frame line disappears when printing in Excel? Mar 21, 2024 am 09:50 AM

If when opening a file that needs to be printed, we will find that the table frame line has disappeared for some reason in the print preview. When encountering such a situation, we must deal with it in time. If this also appears in your print file If you have questions like this, then join the editor to learn the following course: What should I do if the frame line disappears when printing a table in Excel? 1. Open a file that needs to be printed, as shown in the figure below. 2. Select all required content areas, as shown in the figure below. 3. Right-click the mouse and select the &quot;Format Cells&quot; option, as shown in the figure below. 4. Click the “Border” option at the top of the window, as shown in the figure below. 5. Select the thin solid line pattern in the line style on the left, as shown in the figure below. 6. Select &quot;Outer Border&quot;

What functions does Doubao app have? What functions does Doubao app have? Mar 01, 2024 pm 10:04 PM

There will be many AI creation functions in the Doubao app, so what functions does the Doubao app have? Users can use this software to create paintings, chat with AI, generate articles for users, help everyone search for songs, etc. This function introduction of the Doubao app can tell you the specific operation method. The specific content is below, so take a look! What functions does the Doubao app have? Answer: You can draw, chat, write articles, and find songs. Function introduction: 1. Question query: You can use AI to find answers to questions faster, and you can ask any kind of questions. 2. Picture generation: AI can be used to create different pictures for everyone. You only need to tell everyone the general requirements. 3. AI chat: can create an AI that can chat for users,

The difference between vivox100s and x100: performance comparison and function analysis The difference between vivox100s and x100: performance comparison and function analysis Mar 23, 2024 pm 10:27 PM

Both vivox100s and x100 mobile phones are representative models in vivo's mobile phone product line. They respectively represent vivo's high-end technology level in different time periods. Therefore, the two mobile phones have certain differences in design, performance and functions. This article will conduct a detailed comparison between these two mobile phones in terms of performance comparison and function analysis to help consumers better choose the mobile phone that suits them. First, let’s look at the performance comparison between vivox100s and x100. vivox100s is equipped with the latest

What exactly is self-media? What are its main features and functions? What exactly is self-media? What are its main features and functions? Mar 21, 2024 pm 08:21 PM

With the rapid development of the Internet, the concept of self-media has become deeply rooted in people's hearts. So, what exactly is self-media? What are its main features and functions? Next, we will explore these issues one by one. 1. What exactly is self-media? We-media, as the name suggests, means you are the media. It refers to an information carrier through which individuals or teams can independently create, edit, publish and disseminate content through the Internet platform. Different from traditional media, such as newspapers, television, radio, etc., self-media is more interactive and personalized, allowing everyone to become a producer and disseminator of information. 2. What are the main features and functions of self-media? 1. Low threshold: The rise of self-media has lowered the threshold for entering the media industry. Cumbersome equipment and professional teams are no longer needed.

PHP Tips: Quickly Implement Return to Previous Page Function PHP Tips: Quickly Implement Return to Previous Page Function Mar 09, 2024 am 08:21 AM

PHP Tips: Quickly implement the function of returning to the previous page. In web development, we often encounter the need to implement the function of returning to the previous page. Such operations can improve the user experience and make it easier for users to navigate between web pages. In PHP, we can achieve this function through some simple code. This article will introduce how to quickly implement the function of returning to the previous page and provide specific PHP code examples. In PHP, we can use $_SERVER['HTTP_REFERER'] to get the URL of the previous page

What are the functions of Xiaohongshu account management software? How to operate a Xiaohongshu account? What are the functions of Xiaohongshu account management software? How to operate a Xiaohongshu account? Mar 21, 2024 pm 04:16 PM

As Xiaohongshu becomes popular among young people, more and more people are beginning to use this platform to share various aspects of their experiences and life insights. How to effectively manage multiple Xiaohongshu accounts has become a key issue. In this article, we will discuss some of the features of Xiaohongshu account management software and explore how to better manage your Xiaohongshu account. As social media grows, many people find themselves needing to manage multiple social accounts. This is also a challenge for Xiaohongshu users. Some Xiaohongshu account management software can help users manage multiple accounts more easily, including automatic content publishing, scheduled publishing, data analysis and other functions. Through these tools, users can manage their accounts more efficiently and increase their account exposure and attention. In addition, Xiaohongshu account management software has

What is Discuz? Definition and function introduction of Discuz What is Discuz? Definition and function introduction of Discuz Mar 03, 2024 am 10:33 AM

"Exploring Discuz: Definition, Functions and Code Examples" With the rapid development of the Internet, community forums have become an important platform for people to obtain information and exchange opinions. Among the many community forum systems, Discuz, as a well-known open source forum software in China, is favored by the majority of website developers and administrators. So, what is Discuz? What functions does it have, and how can it help our website? This article will introduce Discuz in detail and attach specific code examples to help readers learn more about it.

Do you know how to print ppt with 6 pages per page and two-sided settings? Do you know how to print ppt with 6 pages per page and two-sided settings? Mar 20, 2024 pm 06:36 PM

Sometimes when we use PPT, we often need to print it out. However, we all know that there are many pages in PPT. If we print them one by one, is it really a waste? Therefore, I have personally tested it and it is OK to put 6 PPT pages on one page and then print on both sides. No paper is wasted, and the layout content can be seen clearly. So, do you know how to print 6 double-sided PPT sheets on one page? Next, I will tell you how to set it up. If you are interested, take a look! Step details: 1. First, we find the PPT that needs to be printed on the computer, and then double-click to open it. Click the inverted triangle next to the button on the upper left side of the page, find the [File] button in the drop-down menu, and click it; then, click [Print] in the information that appears. 2. Click

See all articles