第十七章 wxPython的打印构架
本章内容
用
wxPython
打印创建和显示打印对话框
- 创建和显示页面设置对话框
- 在你的程序中执行打印
- 执行一个打印预览
在第16章中,我们已经关注了wxPython
的一打印方法:使用wx.HtmlEasyPrinting
。如果你用该方法打印HTML
(或某些容易转换为HTML
的文件)的话,这个方法将会工作的很好,但是要作为一个完善打印办法还是不够的。在wxPython
中还有一个更为通用的打印构架,你可以用它来打印你想打印的任何东西。基本上,该构架使你能够使用设备上下文和绘制操作来执行打印。你也可以创建打印预览。
本章将讨论该构架中最重要的类:wx.Printout
,它管理实际的图片部分。打印输出实例可以由一个代表打印机的wx.Printer
对象或用于打印预览的wx.PrintPreview
对象来管理。多们也将讨论几个管理与打印相关的数据的类,以及用来显示信息给用户的对话框。
如何用wxPython打印?
我们将以类wx.Printout
作为开始。首先你要创建你自定义的wx.Printout
的子类。接着你要覆盖wx.Printout
的方法以定义你自定义的打印行为。wx.Printout
有7个你可以覆盖以自定义打印行为的方法。这些方法在一个打印会话过程期间被wxPython
自动调用。图17.1其中的六个方法,它们被特定的事件触发。在大多数情况下,你不需要全部覆盖它们。
图17.1
理解打印输出的生命周期
你通过创建一个你的打印输出对象的实例和一个类wx.Printer
的实例启动一个打印会话:
wx.Printer(data=None)
可选的data
参数是wx.PrintDialogData
的一个实例。要开始实际的打印,需要调用wx.Printer
的Print(parent, printout, prompt=True)
方法。参数parent
是父窗口(它被用作对话框的窗口中)。参数printout
是你的wx.Printout
实例。如果参数prompt
为True
,那么在打印之前,wxPython
将显示打印对话框,否则不显示。
在Print()
方法开始后,它调用wx.Printout
的第一个可被覆盖的方法OnPreparePrint()
。OnPreparePrint()
方法在wx.Printout
实例做任何其它的事之前被确保调用,因此该方法是放置收集你的数据或做那些必须在打印开始之前所要做的计算的一个好的地方。实际的打印使用OnBeginPrinting()
方法开始,你可以对该方法进行覆盖,以自定主你想要的行为——默认情况下,该方法什么也不做。OnBeginPrinting()
在整个打印会话中只会被调用一次。
你希望打印的文档的每个单独的拷贝触发对OnBeginDocument(startPage, endPage)
的一个调用,其中参数startPage, endPage
告诉wxPython
打印的起始页和最后一页。这两个参数都应该指定。如果你想覆盖这个方法,那么你必须调用它的基类的方法,因为基类的方法要做一些重要的工作(如调用wx.DC.StartDoc()
)。在wxPython
中,你可以使用base_OnBeginDocument(startPage, endPage)
来调用其父类的方法。如果OnBeginDocument
返回False
,那么将取消打印工作。
你最有可能去覆盖的方法是OnPrintPage(pageNum)
,该方法是你放置关于每一页的绘制命令的地方。参数pageNum
是要打印的页的页码。在这个方法中,你调用GetDC()
,GetDC()
根据你当前的系统平台返回一个适当的设备上下文。对于实际的打印,如果你是在一个微软的Windows
系统上的话,那么GetDC()
返回的是类wx.PrinterDC
的实例。对于其它的系统,返回的是类wx.PostScriptDC
的实例。如果你是处在一个打印预览操作中,那么对于任何的操作系统,GetDC()
返回的都是一个wx.MemoryDC
。一旦你有了设备上下文,你就可以做你想做的设备上下文绘制操作,并且它们将被打印或预览。
在一个文档的副本打印结束后,一个OnEndDocument()
调用被触发。另外,如果你要覆盖OnEndDocument()
方法,那么你必须调用其基类的方法base_OnEndDocument()
。base_OnEndDocument()
将调用wx.DC.EndDoc()
方法。当你的所有的副本被打印完后,OnEndPrinting()
方法被调用,这样就结束了打印会话。
wx.Printout
还有另一个可被覆盖的方法:HasPage(pageNum)
。该方法通常需要被覆盖,它被打印架构用于循环控制。如果参数pageNum
存在于文档中,那么该方法返回True
,否则返回False
。
实战打印构架
下面我们将通过一个例子来展示打印构架实际上是如何工作的。这个例子由一个简单的用于打印文本文件的构架组成,并且应用程序让你能够键入简单的文本。图17.2显示了这个应用程序的结果。
图17.1
例17.1显示了我们已经讨论过的打印构架和我们将要接触的打印对话框机制。
例17.1 打印构架的一个较长的例子
import wx
import os
FONTSIZE = 10
class TextDocPrintout(wx.Printout):
"""
A printout class that is able to print simple text documents.
Does not handle page numbers o titles, and it assumes that no
lines are longer than what will fit within the page width. Those
features are left as an exercise for the reader. ;-)
"""
def __init__(self, text, title, margins):
wx.Printout.__init__(self, title)
self.lines = text.split('\n')
self.margins = margins
def HasPage(self, page):
return page = self.numPages
def GetPageInfo(self):
return (1, self.numPages, 1, self.numPages)
def CalculateScale(self, dc):
# Scale the DC such that the printout is roughly the same as
# the screen scaling.
ppiPrinterX, ppiPrinterY = self.GetPPIPrinter()
ppiScreenX, ppiScreenY = self.GetPPIScreen()
logScale = float(ppiPrinterX)/float(ppiScreenX)
# Now adjust if the real page size is reduced (such as when
# drawing on a scaled wx.MemoryDC in the Print Preview.) If
# page width == DC width then nothing changes, otherwise we
# scale down for the DC.
pw, ph = self.GetPageSizePixels()
dw, dh = dc.GetSize()
scale = logScale * float(dw)/float(pw)
# Set the DC's scale.
dc.SetUserScale(scale, scale)
# Find the logical units per millimeter (for calculating the
# margins)
self.logUnitsMM = float(ppiPrinterX)/(logScale*25.4)
def CalculateLayout(self, dc):
# Determine the position of the margins and the
# page/line height
topLeft, bottomRight = self.margins
dw, dh = dc.GetSize()
self.x1 = topLeft.x * self.logUnitsMM
self.y1 = topLeft.y * self.logUnitsMM
self.x2 = dc.DeviceToLogicalXRel(dw) - bottomRight.x * self.logUnitsMM
self.y2 = dc.DeviceToLogicalYRel(dh) - bottomRight.y * self.logUnitsMM
# use a 1mm buffer around the inside of the box, and a few
# pixels between each line
self.pageHeight = self.y2 - self.y1 - 2*self.logUnitsMM
font = wx.Font(FONTSIZE, wx.TELETYPE, wx.NORMAL, wx.NORMAL)
dc.SetFont(font)
self.lineHeight = dc.GetCharHeight()
self.linesPerPage = int(self.pageHeight/self.lineHeight)
def OnPreparePrinting(self):
# calculate the number of pages
dc = self.GetDC()
self.CalculateScale(dc)
self.CalculateLayout(dc)
self.numPages = len(self.lines) / self.linesPerPage
if len(self.lines) % self.linesPerPage != 0:
self.numPages += 1
def OnPrintPage(self, page):
dc = self.GetDC()
self.CalculateScale(dc)
self.CalculateLayout(dc)
# draw a page outline at the margin points
dc.SetPen(wx.Pen("black", 0))
dc.SetBrush(wx.TRANSPARENT_BRUSH)
r = wx.RectPP((self.x1, self.y1),
(self.x2, self.y2))
dc.DrawRectangleRect(r)
dc.SetClippingRect(r)
# Draw the text lines for this page
line = (page-1) * self.linesPerPage
x = self.x1 + self.logUnitsMM
y = self.y1 + self.logUnitsMM
while line (page * self.linesPerPage):
dc.DrawText(self.lines[line], x, y)
y += self.lineHeight
line += 1
if line = len(self.lines):
break
return True
class PrintFrameworkSample(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, size=(640, 480),
title="Print Framework Sample")
self.CreateStatusBar()
# A text widget to display the doc and let it be edited
self.tc = wx.TextCtrl(self, -1, "",
style=wx.TE_MULTILINE|wx.TE_DONTWRAP)
self.tc.SetFont(wx.Font(FONTSIZE, wx.TELETYPE, wx.NORMAL, wx.NORMAL))
filename = os.path.join(os.path.dirname(__file__), "sample-text.txt")
self.tc.SetValue(open(filename).read())
self.tc.Bind(wx.EVT_SET_FOCUS, self.OnClearSelection)
wx.CallAfter(self.tc.SetInsertionPoint, 0)
# Create the menu and menubar
menu = wx.Menu()
item = menu.Append(-1, "Page Setup...\tF5",
"Set up page margins and etc.")
self.Bind(wx.EVT_MENU, self.OnPageSetup, item)
item = menu.Append(-1, "Print Setup...\tF6",
"Set up the printer options, etc.")
self.Bind(wx.EVT_MENU, self.OnPrintSetup, item)
item = menu.Append(-1, "Print Preview...\tF7",
"View the printout on-screen")
self.Bind(wx.EVT_MENU, self.OnPrintPreview, item)
item = menu.Append(-1, "Print...\tF8", "Print the document")
self.Bind(wx.EVT_MENU, self.OnPrint, item)
menu.AppendSeparator()
item = menu.Append(-1, "E ", "Close this application")
self.Bind(wx.EVT_MENU, self.OnExit, item)
menubar = wx.MenuBar()
menubar.Append(menu, " ")
self.SetMenuBar(menubar)
# initialize the print data and set some default values
self.pdata = wx.PrintData()
self.pdata.SetPaperId(wx.PAPER_LETTER)
self.pdata.SetOrientation(wx.PORTRAIT)
self.margins = (wx.Point(15,15), wx.Point(15,15))
def OnExit(self, evt):
self.Close()
def OnClearSelection(self, evt):
evt.Skip()
wx.CallAfter(self.tc.SetInsertionPoint,
self.tc.GetInsertionPoint())
def OnPageSetup(self, evt):
data = wx.PageSetupDialogData()
data.SetPrintData(self.pdata)
data.SetDefaultMinMargins(True)
data.SetMarginTopLeft(self.margins[0])
data.SetMarginBottomRight(self.margins[1])
dlg = wx.PageSetupDialog(self, data)
if dlg.ShowModal() == wx.ID_OK:
data = dlg.GetPageSetupData()
self.pdata = wx.PrintData(data.GetPrintData()) # force a copy
self.pdata.SetPaperId(data.GetPaperId())
self.margins = (data.GetMarginTopLeft(),
data.GetMarginBottomRight())
dlg.Destroy()
def OnPrintSetup(self, evt):
data = wx.PrintDialogData(self.pdata)
dlg = wx.PrintDialog(self, data)
dlg.GetPrintDialogData().SetSetupDialog(True)
dlg.ShowModal();
data = dlg.GetPrintDialogData()
self.pdata = wx.PrintData(data.GetPrintData()) # force a copy
dlg.Destroy()
def OnPrintPreview(self, evt):
data = wx.PrintDialogData(self.pdata)
text = self.tc.GetValue()
printout1 = TextDocPrintout(text, "title", self.margins)
printout2 = None #TextDocPrintout(text, "title", self.margins)
preview = wx.PrintPreview(printout1, printout2, data)
if not preview.Ok():
wx.MessageBox("Unable to create PrintPreview!", "Error")
else:
# create the preview frame such that it overlays the app frame
frame = wx.PreviewFrame(preview, self, "Print Preview",
pos=self.GetPosition(),
size=self.GetSize())
frame.Initialize()
frame.Show()
def OnPrint(self, evt):
data = wx.PrintDialogData(self.pdata)
printer = wx.Printer(data)
text = self.tc.GetValue()
printout = TextDocPrintout(text, "title", self.margins)
useSetupDialog = True
if not printer.Print(self, printout, useSetupDialog) \
and printer.GetLastError() == wx.PRINTER_ERROR:
wx.MessageBox(
"There was a problem printing.\n"
"Perhaps your current printer is not set correctly?",
"Printing Error", wx.OK)
else:
data = printer.GetPrintDialogData()
self.pdata = wx.PrintData(data.GetPrintData()) # force a copy
printout.Destroy()
app = wx.PySimpleApp()
frm = PrintFrameworkSample()
frm.Show()
app.MainLoop()
例17.2中的打印输出类能够打印简单的文本文档,但是不能处理页码或标题,并且它创假设了行的宽度没有超过页面的宽度。对于例子的完善就留给读者作为一个练习。
上面最重要的代码片断是在构架的OnPreparePrinting()
和OnPrintPage()
以及示例窗口的OnPrint()
方法中。
使用wx.Printout的方法工作
在wx.Printout
中有几个get
*方法,它们使你能够获取当前打印环境的有关信息。表17.1列出了这些方法。
表17.1 wx.Printout
的信息获取方法
GetDC() |
该方法返回关于打印机或打印预览的用于绘制文档的设备上下文。 |
GetPageInfo() |
返回一个含有四个元素的元组(minPage, maxPage, pageFrom, pageTo) 。minPage, maxPage 分别是所允许的最小和最大页码,默认是1和32000。pageFrom, pageTo 是必须被打印的范围,默认为1。你可以在你的子类中覆盖这个方法。 |
GetPageSizeMM() |
返回包含一个页面的宽度和高度的一个(w, h) 元组,以毫米为单位。 |
GetPageSizePixels() |
返回一个页面的宽度和高度的一个(w, h) 元组,以像素为单位。如果打印输出被用于打印预览,那么像素数将反应当前的缩放比列,意思就是说像素将会随缩放比列而变。 |
GetPPIPrinter() |
返回当前打印机在垂直和水平方向上每英寸的像素的一个(w, h) 元组。在预览中,这个值也是始终一致的,即使打印预览的缩放比列变化了。 |
GetPPIScreen() |
返回当前屏幕在垂直和水平方向上每英寸的像素的一个(w, h) 元组。在预览中,这个值也是始终一致的,即使打印预览的缩放比列变化了。 |
GetTitle() |
返回打印输出的标题。 |
在后面的几节中,我们将讨论如何呈现打印对话框给用户。
如何显示打印对话框?
诸如要打印那些面面,要打印多少副本这些关于打印工作的数据是由标准的打印对话框来管理的。打印对话框是与字体和颜色对话框类似的,wxPython
中的打印对话框实例仅仅是对本地控件和一个储存了对话框数据的分离的数据对象的简单封装。
创建一个打印对话框
图17.3显示了打印设置对话框的样例。
图17.3
这里的对话框是类wx.PrintDialog
的一个实例,你可以使用下面的构造函数来得到:
wx.PrintDialog(parent, data=None)
其中,参数parent
是对话框的父框架,参数data
是一个预先存在的wx.PrintDialogData
实例,它用于对话框的初始数据。
使用方法
一旦你有了打印对话框,你就可以使用标准的ShowModal()
方法来显示它,ShowModal()
方法将根据用户关闭对话框的方式而返回wx.ID_OK
或wx.ID_CANCEL
。 在你关闭了对话框之后,你可以使用GetPrintDialogData()
方法来得到用户输入的数据。你也可以使用GetPrintDC()
方法得到与数据相关联的打印机的设备上下文,如果还没有内容被创建,那么GetPrintDC()
方法返回None
。例17.1中的OnPrintSetup()
方法显示了实际上对话框是如何被获取的。
使用属性
这个数据对象本身有几个属性,其中的一个是对wx.PrintData
类型的一个对象的引用,wx.PrintData
有更多的属性。你可以使用构造函数wx.PrintDialogData()
来创建你的wx.PrintDialogData
对象。这使得你能够在打开对话框之前预设属性。
wx.PrintDialogData
对象有四个属性用于控制打印对话框的各个部分的有效性。方法EnableHelp(enable)
用于开关帮助性能。至于对话框的其它部分,EnablePageNumbers(enable)
与页面数量输入框相关,EnablePrintToFile(enable)
管理实际的打印按钮,EnableSelection(enable)
在打印所有和仅打印被选项之间作切换。
表17.2显示了对话框数据对象的其它属性,它们使你能够管理有关打印请求的信息。
表17.2 wx.PrintDialogData
的属性
GetAllPages() |
如果用户选择了打印整个文档这一选项,则返回True 。 |
SetCollate(flag) |
|
GetCollate() |
如果用户选择了核对打印的页,则返回True 。 |
SetFromPage(page) |
|
GetFromPage() |
如果用户选择从某一页打印,那么方法返回打印的第一页的整数页码。 |
SetMaxPage(page) |
|
GetMaxPage() |
返回文档中最大的页码。 |
SetMinPage(page) |
|
GetMinPage() |
返回文档中最小的页码。 |
SetNoCopies() |
|
GetNoCopies() |
返回用户选择要打印的副本的数量。 |
SetPrintData(printData) |
|
GetPrintData() |
返回与对话框相关联的wx.PrintData 对象。 |
SetPrintToFile(flag) |
|
GetPrintToFile() |
如果用户已经选择了打印到一个文件这一项,那么返回True 。“打印到文件”这一机制由wxPython 管理。 |
SetSelection(flag) |
|
GetSelection() |
如果用户已经选择了只打印当前的选择这一项,那么返回True 。 |
SetToPage(page) |
|
GetToPage() |
如果用户指定了一个范围,那么返回打印的最后一页的页码。 |
被GetPrintData()
方法返回的wx.PrintData
实例提供了有关打印的更进一步的信息。通常这些信息是在你的打印对话框的打印设置子对话框中的。表17.3列出了wx.PrintData
对象的属性。
表17.3 wx.PrintData
的属性
SetColour(flag) |
||
GetColour() |
如果当前的打印是用于颜色打印的,那么返回True 。 |
|
SetDuplex(mode) |
||
GetDuplex() |
返回当前关于双面打印的设置。值可以是wx.DUPLEX_SIMPLE (非双面打印),wx.DUPLEX_HORIZONTAL (横向双面打印),wx.DUPLEX_VERTICAL (纵向双面打印)。 |
|
SetOrientation(orientation) |
||
GetOrientation() |
返回纸张的打印定位(肖像或风景)。值可以是wx.LANDSCAPE 和wx.PORTRAIT 。 |
|
SetPaperId(paperId) |
||
GetPaperId() |
返回匹配纸张类型的标识符。通常的值有wx.PAPER_LETTER, wx.PAPER_LEGAL, 和wx.PAPER_A4 。完整的页面(纸张)ID 的列表见wxWidgets 文档。 |
|
SetPrinterName(printerName) |
||
GetPrinterName() |
返回被系统引用的当前打印机的名字。如果该值为空字符串,那么默认打印机被使用。 | |
SetQuality(quality) |
||
GetQuality() |
返回打印机的当前品质值。set *方法仅接受如下取值 |
wx.PRINT_QUALITY_DRAFT, wx.PRINT_QUALITY_HIGH, wx.PRINT_QUALITY_MEDIUM, 或wx.PRINT_QUALITY_LOW 。get *方法将返回上面的这些值之一,或一个代表每英寸点数设置的正整数。 |
如何显示页面设置对话框?
图17.4显示了页面设置对话框是如何让用户来设置与页面尺寸相关的数据的。
图17.4
创建页面设置对话框
你可以通过实例化一个wx.PageSetupDialog
类来创建一个页面设置对话框。
wx.PageSetupDialog(parent, data=None)
参数parent
是新的对话框的父窗口。参数data
是wx.PageSetupDialogData
的一个实例默认为None
。一旦页面设置对话框被创建了,那么这个对话框的行为就和其它任何模式对话框一样,并且你可以使用ShowModal()
来显示它。通常,返回值表明了用户是否是使用wx.ID_OK
或wx.ID_CANCEL
按钮关闭的对话框窗口。在对话框关闭后,你可以通过调用GetPageSetupDialogData()
来取得对数据对象的访问, GetPageSetupDialogData()
返回类wx.PageSetupDialogData
的一个实例。
使用页面设置属性工作
wx.PageSetupDialogData
类有几个必须与页面设置一起使用的属性。表17.4展示了控制对话框自身显示的属性。除非有其它的指定,否则所有这些属性都默认为True
。
表17.4 wx.PageSetupDialogData
的对话框控制属性
GetDefaultMinMargins() |
|
SetDefaultMinMargins(flag) |
如果这个属性为True ,并且你是在微软的Windows 系统上,那么页面设置将使用默认打印机的当前属性作为默认认的最小化页边距。否则,它将使用系统默认值。 |
GetDefaultInfo() |
|
SetDefaultInfo(flag) |
如果这个属性为True ,并且你是在微软的Windows 系统上,那么这个页面设置对话框不会被显示。替而代之,当前打印机的所有默认值都将被放入数据对象。 |
EnableHelp(flag) |
|
GetEnableHelp() |
如果为True ,那么对话框的帮助部分是有效的。 |
EnableMargins(flag) |
|
GetEnableMargins() |
如果为True ,那么对话框的用于调整页边距的部分是有效的。 |
EnableOrientation(flag) |
|
GetEnableOrientation() |
如果为True ,那么对话框的用于改变页面定位的部分是有效的。 |
EnablePaper(flag) |
|
GetEnablePaper() |
如果为True ,那么对话框的用于允许用户改变页面(纸张)类型的部分是效的。 |
EnablePrinter(flag) |
|
GetEnablePrinter() |
如果为True ,那么允许用户设置打印机的按钮是有效的。 |
表17.5显示了wx.PageSetupDialogData
类的附加的属性,这些属性用于控制页面的边距和尺寸。
表17.5 wx.PageSetupDialogData
的页边距和尺寸属性
GetMarginTopLeft() |
|
SetMarginTopLeft(pt) |
get 方法返回一个wx.Point ,其中的值x是当前的左边距,y是当前的上边距。set 方法允许你使用一个wx.Point 或一个Python 元组来改变这些值。 |
GetMarginBottomRight() |
|
SetMarginBottomRight(pt) |
get 方法返回一个wx.Point ,其中的值x是当前的右边距,y是当前的下边距。set 方法允许你使用一个wx.Point 或一个Python 元组来改变这些值。 |
GetMinMarginTopLeft() |
|
SetMinMarginTopLeft(pt) |
同GetMarginTopLeft() 中的一样,只是值是所允许的最小左边距和上边距。 |
GetMinMarginBottomRight() |
|
SetMinMarginBottomRight(pt) |
同GetMarginBottomRight() 中的一样,只是值是所允许的最小右边距和下边距。 |
GetPaperId() |
|
SetPaperId(id) |
返回关于当前页面类型的wxPython 标识符。同wx.PrinterData 的属性。 |
GetPaperSize() |
|
SetPaperSize(size) |
get *方法返回包含页面的水平和坚直方向尺寸的一个wx.Size 实例。单位是毫米。 |
GetPrintData() |
|
SetPrintData(printData) |
get *方法返回与当前打印会话相关的wx.PrintData 实例。 |
到目前为止,我们已经讨论了所有关于数据对话框的整改,下面我们将重点放在打印上面。
如何打印?
到目前为止,我们已经见过了打印构架的所有部分,现是我们打印一些东西的时候了。实际的打印部分是由wx.Printer
类的一个实例来控制的。与已经说明的其它部分相比,打印并不更简单。接下来,我们将对在例17.1中的OnPrint()
中的步骤作介绍。
第一步 按顺序得到你的所有数据
这至少应该包括带有打印机命令的wx.Printout
对象,通常也要包括一个wx.PrintDialogData
实例。
第二步 创建一个wx.Printer
实例
创建该实例,要使用构造器wx.Printer(data=None)
。可选参数data
是一个wx.PrintDialogData
实例。该数据控制打印,通常,你会想使用它。
第三步 使用wx.Printer
的Print ()
方法打印
Print()
方法如下:
Print(parent, printout, prompt=True)
其中参数parent
是当打印时所触发的对话框的父窗口。printout
是用于打印的wx.Printout
对象。如果参数prompt
为True
,那么在打印之前显示打印对话框,否则将立即;启动打印。
如果打印成功,则Print()
方法返回True
。你能够调用GetLastError()
方法来得到下列常量之一:wx.PRINTER_CANCELLED
(如果失败是由于用户取消了打印所引起的),wx.PRINTER_ERROR
(如果失败在打印期间由打印自身所引起的),或wx.PRINTER_NO_ERROR
(如果Print()
返回True
且没有错误发生)。
这儿还有另外两个你可以使用一个wx.Printer
实例做的事:
你可以使用
CreateAbortWindow(parent,printout)
来显示中止对话框,其中参数parent
和printout
同Print()
方法中的。如果用户已经中止打印任务,你能够通过调用Abort()
来发现,该方法在这种情况下返回True
。你可以使用
PrintDialog(parent)
来显式地显示打印对话框,并且你可以使用GetPrintDialogData()
来得到活动的打印数据对象。
如何实现一个打印预览?
使用设备上下文的一个好处就是很容易管理打印预览,你可以使用一个屏幕设备上下文来代替打印机设备上下文。接下来的三个部分将讨论打印预览的过程。
第一步 创建预览实例
在一个打印预览中的第一步是创建类wx.PrintPreview
的一个实例,wx.PrintPreview
类似wx.Printer
。构造器如下:
wx.PrintPreview(printout, printoutForPrinting, data=None)
其中参数printout
是一个wx.Printout
对象,用于管理预览。参数printoutForPrinting
是另一个wx.Printout
对象。如果它不是None
,那么当显示的时候,该打印预览窗口包含一Print
按钮,该按钮启动打印。printoutForPrinting
用于实际的打印。如果参数printoutForPrinting
为None
,那么Print
按钮不显示。当然,你可以传递同一个实例或你的自定义打印输出类的相同版本的两个实例给参数printout
和printoutForPrinting
。参数data
可以是一个wx.PrintData
对象或一个wx.PrintDialogData
对象。如果参数data
指定了的话,那么它被用于控制该打印预览。在例17.1中,我们显示了一个在OnPrintPreview()
方法中使用打印预览的例子。
第二步 创建预览框架
一旦你有了你的wx.PrintPreview
,你就需要一框架以在其中观看你的wx.PrintPreview
。该框架由类wx.PreviewFrame
提供,wx.PreviewFrame
是wx.Frame
的一个子类,wx.Frame
为预览提供基本的用户交互控件。wx.PreviewFrame
的构造器如下:
wx.PreviewFrame(preview, parent, title, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE,
name="frame")
其中真正有意义的参数是preview
,它是要被预览的wx.PrintPreview
实例。其它的参数都是标准的wx.Frame
中的。wx.PreviewFrame
不定义任何自定义的样式或事件。
第三步 初始化框架
在你显示你的wx.PreviewFrame
之前,你需要调用Initialize()
方法,该方法创建窗口的内部的部件并做其它的内部的计算。一旦你Show()
了该框架,那么如果你想再改变预览窗口的感观,你可以使用考虑CreateControlBar()
和CreateCanvas()
方法,它们分别创建类wx.PreviewControlBar
和wx.PreviewCanvas
的对象。覆盖这些方法以创建你自己的画布(canvas)
和/或控制栏对象,使得你能够定制你的打印预览窗口的感观。
本章小结
1、这是wxPython
中的一个通用的打印构架,它不仅可以打印HTML
,还可以打印任何能够被绘制到设备上下文的东西。这个架构中的主要的类是wx.Printout
,但是wx.Printer
和wx.PrintPreview
也是重要的。
2、wx.Printout
类管理图形打印的细节,并且它包含几个可以被覆盖来定制打印会话期间的行为和使用的数据的方法。打印发生在OnPrintPage()
方法期间。
3、用于打印机设置和页面设置的标准的对话框是可以从wxPython
来访问的。打印机设置对话框是wx.PrintDialog
的一个实例,页面设置对话框是wx.PageSetupDialog
的一个实例。这两个对话框都有相关的数据类,数据类使你的程序可以处理所有显示在对话框中的值。
4、一旦有了数据,那么实际将数据传送给打印机则是wx.Printer
类的相对简单的应用。你可以使用wx.PrintPreview
类来管理一个打印预览会话,该类包括一个打印预览框架,和根据该框架指定通常打印行为的选项。