How to use printing framework - Part 1 (Phoenix)
Keywords : Printing, Printout, Preview, Printer, PrintData, PrintDialogData, PageSetupDialogData, PageSetupDialog, PrintPreview, PreviewFrame, Canvas, Grid, HtmlEasyPrinting, PDFViewer, PDFWindow, ReportLab.
Contents
Introduction
The Printer framework for wx.Windows / wx.Python is quite complicated.
Because of this, wx.HtmlEasyPrinting is provided to help simplify basic printing functionality.
This Recipe covers a simplified approach to using both wx.HtmlEasyPrinting and the more complicated wx.Printout.
What Objects are Involved
The following classes will be used in these recipes :
wx.HtmlEasyPrinting -- The simple way to print
wx.Printout -- Base printing class that will be inherited from. Various control functions handling printing events are defined here.
wx.PrintData -- Printer / page configuration data
wx.PrintDialogData -- (same as (wx.PrintData) except what is used by Page Setup window ??)
wx.Printer -- Software interface to the printer
wx.MessageBox -- Used for alerting the user to any problems
wx.PrintPreview -- Used for print preview
wx.PrintDialog -- Window that pops up, asking how many pages to print, etc..
Demonstrating :
Tested py3.x, wx4.x and Win10.
Printing is an essential element for your programs, here we show you how to print.
Are you ready to use some samples ?
Test, modify, correct, complete, improve and share your discoveries !
Direct printing
1 # sample_one.py
2
3 import sys
4 import os
5 import platform
6 import wx
7
8 # class My_Frame
9 # class My_App
10
11 #-------------------------------------------------------------------------------
12
13 if os.name == "posix":
14 print("\nPlatform : UNIX - Linux")
15 elif os.name in ['nt', 'dos', 'ce']:
16 print("\nPlatform : Windows")
17 else:
18 print("\nPlatform : ", platform.system())
19
20 #-------------------------------------------------------------------------------
21
22 class My_Frame(wx.Frame):
23 """
24 Create a main frame for my application.
25 """
26 def __init__(self, parent, id, title=""):
27 wx.Frame.__init__(self,
28 parent,
29 id,
30 title,
31 size=(600, 350),
32 style=wx.DEFAULT_FRAME_STYLE)
33
34 #------------
35
36 # Simplified init method.
37 self.SetProperties()
38 self.CreateMenu()
39 self.CreateCtrls()
40 self.BindEvents()
41 self.DoLayout()
42
43 #------------
44
45 self.CenterOnScreen()
46
47 #---------------------------------------------------------------------------
48
49 def SetProperties(self):
50 """
51 Set the main frame properties (title, icon...).
52 """
53
54 frameicon = wx.Icon("Icons/wxWidgets.ico")
55 self.SetIcon(frameicon)
56
57 #------------
58
59 self.SetTitle("Printing test...")
60
61
62 def CreateMenu(self):
63 """
64 Make the frame menus.
65 """
66
67 menub = wx.MenuBar()
68
69 fmenu = wx.Menu()
70 fmenu.Append(wx.ID_PRINT, "&Print\tCtrl+P")
71 fmenu.AppendSeparator()
72 fmenu.Append(wx.ID_EXIT, "E&xit\tCtrl+X")
73 menub.Append(fmenu, "&File")
74
75 self.SetMenuBar(menub)
76
77
78 def CreateCtrls(self):
79 """
80 Make widgets for my application.
81 """
82
83 boldFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
84 boldFont.SetWeight(wx.BOLD)
85 boldFont.SetPointSize(10)
86
87 #------------
88
89 # First create the controls.
90 self.panel = wx.Panel(self,
91 id=-1,
92 style=wx.BORDER_THEME|
93 wx.TAB_TRAVERSAL)
94
95 self.text = wx.StaticText(self.panel,
96 id=-1,
97 label="Demonstrating :")
98 self.text.SetFont(boldFont)
99
100 self.info = wx.StaticText(self.panel,
101 id=-1,
102 label="> Direct printing.")
103 self.info.SetForegroundColour("red")
104
105 self.tc = wx.TextCtrl(self.panel,
106 id=-1,
107 size=(200, -1),
108 value="Hello, World ! A sample text.")
109
110 self.btnPrint = wx.Button(self.panel,
111 id=wx.ID_PRINT,
112 label="")
113 self.btnPrint.SetFocus()
114
115 self.btnClose = wx.Button(self.panel,
116 id=wx.ID_CLOSE,
117 label="E&xit")
118
119
120 def BindEvents(self):
121 """
122 Bind all the events related to my application.
123 """
124
125 # Bind some menu events to an events handler.
126 self.Bind(wx.EVT_MENU, self.OnBtnPrint, id=wx.ID_PRINT)
127 self.Bind(wx.EVT_MENU, self.OnBtnClose, id=wx.ID_EXIT)
128
129 # Bind the close event to an event handler.
130 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
131
132 # Bind some buttons events to an events handler.
133 self.Bind(wx.EVT_BUTTON, self.OnBtnPrint, self.btnPrint)
134 self.Bind(wx.EVT_BUTTON, self.OnBtnClose, self.btnClose)
135
136
137 def DoLayout(self):
138 """
139 Manage widgets Layout.
140 """
141
142 # MainSizer is the top-level one that manages everything.
143 mainSizer = wx.BoxSizer(wx.VERTICAL)
144
145 #------------
146
147 hBox1 = wx.BoxSizer(wx.HORIZONTAL)
148 hBox1.Add(self.info, 0, wx.ALL, 15)
149
150 #------------
151
152 hBox2 = wx.BoxSizer(wx.HORIZONTAL)
153 hBox2.Add(self.btnPrint, 0, wx.ALL, 10)
154 hBox2.Add(self.btnClose, 0, wx.ALL, 10)
155
156 #------------
157
158 mainSizer.Add(self.text, 0, wx.ALL, 10)
159 mainSizer.Add(wx.StaticLine(self.panel),
160 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5)
161 mainSizer.Add(self.tc, 0, wx.ALL, 15)
162 mainSizer.Add(hBox1, 0, wx.ALL, 5)
163 mainSizer.Add(hBox2, 0, wx.ALL, 5)
164
165 #------------
166
167 # Finally, tell the panel to use the mainSizer for layout.
168 self.panel.SetSizer(mainSizer)
169
170
171 def OnBtnPrint(self, event):
172 """
173 Print the document.
174 """
175
176 text = self.tc.GetValue()
177
178 #------------
179
180 pd = wx.PrintData()
181
182 pd.SetPrinterName("")
183 pd.SetOrientation(wx.PORTRAIT)
184 pd.SetPaperId(wx.PAPER_A4)
185 pd.SetQuality(wx.PRINT_QUALITY_DRAFT)
186 # Black and white printing if False.
187 pd.SetColour(True)
188 pd.SetNoCopies(1)
189 pd.SetCollate(True)
190
191 #------------
192
193 pdd = wx.PrintDialogData()
194
195 pdd.SetPrintData(pd)
196 pdd.SetMinPage(1)
197 pdd.SetMaxPage(1)
198 pdd.SetFromPage(1)
199 pdd.SetToPage(1)
200 pdd.SetPrintToFile(False)
201 # pdd.SetSetupDialog(False)
202 # pdd.EnableSelection(True)
203 # pdd.EnablePrintToFile(True)
204 # pdd.EnablePageNumbers(True)
205 # pdd.SetAllPages(True)
206
207 #------------
208
209 dlg = wx.PrintDialog(self, pdd)
210
211 if dlg.ShowModal() == wx.ID_OK:
212 dc = dlg.GetPrintDC()
213
214 dc.StartDoc("My document title")
215 dc.StartPage()
216
217 # (wx.MM_METRIC) ---> Each logical unit is 1 mm.
218 # (wx.MM_POINTS) ---> Each logical unit is a "printer point" i.e.
219 dc.SetMapMode(wx.MM_POINTS)
220
221 dc.SetTextForeground("red")
222 dc.SetFont(wx.Font(20, wx.SWISS, wx.NORMAL, wx.BOLD))
223 dc.DrawText(text, 50, 100)
224
225 dc.EndPage()
226 dc.EndDoc()
227 del dc
228
229 else :
230 dlg.Destroy()
231
232
233 def OnBtnClose(self, event):
234 """
235 ...
236 """
237
238 self.Close(True)
239
240
241 def OnCloseWindow(self, event):
242 """
243 ...
244 """
245
246 self.Destroy()
247
248 #-------------------------------------------------------------------------------
249
250 class My_App(wx.App):
251 """
252 ...
253 """
254 def OnInit(self):
255
256 #------------
257
258 frame = My_Frame(None, id=-1)
259 self.SetTopWindow(frame)
260 frame.Show(True)
261
262 return True
263
264 #-------------------------------------------------------------------------------
265
266 def main():
267 app = My_App(False)
268 app.MainLoop()
269
270 #-------------------------------------------------------------------------------
271
272 if __name__ == "__main__" :
273 main()
Printout class
1 # sample_two.py
2
3 import sys
4 import os
5 import platform
6 import wx
7
8 # class My_Printout
9 # class My_Frame
10 # class My_App
11
12 #-------------------------------------------------------------------------------
13
14 if os.name == "posix":
15 print("\nPlatform : UNIX - Linux")
16 elif os.name in ['nt', 'dos', 'ce']:
17 print("\nPlatform : Windows")
18 else:
19 print("\nPlatform : ", platform.system())
20
21 #-------------------------------------------------------------------------------
22
23 class My_Printout(wx.Printout):
24 """
25 Create a printout.
26 """
27 def __init__(self, text, title):
28 wx.Printout.__init__(self, title)
29
30 #------------
31
32 self.lines = text
33
34 #---------------------------------------------------------------------------
35
36 def OnBeginDocument(self, start, end):
37 """
38 ...
39 """
40
41 return super(My_Printout, self).OnBeginDocument(start, end)
42
43
44 def OnEndDocument(self):
45 """
46 ...
47 """
48
49 super(My_Printout, self).OnEndDocument()
50
51
52 def OnBeginPrinting(self):
53 """
54 ...
55 """
56
57 super(My_Printout, self).OnBeginPrinting()
58
59
60 def OnEndPrinting(self):
61 """
62 ...
63 """
64
65 super(My_Printout, self).OnEndPrinting()
66
67
68 def OnPreparePrinting(self):
69 """
70 ...
71 """
72
73 super(My_Printout, self).OnPreparePrinting()
74
75
76 def HasPage(self, page):
77 """
78 ...
79 """
80
81 if page <= 2:
82 return True
83 else:
84 return False
85
86
87 def GetPageInfo(self):
88 """
89 ...
90 """
91
92 return (1, 2, 1, 2)
93
94
95 def OnPrintPage(self, page):
96 """
97 ...
98 """
99
100 dc = self.GetDC()
101
102 # (wx.MM_METRIC) ---> Each logical unit is 1 mm.
103 # (wx.MM_POINTS) ---> Each logical unit is a "printer point" i.e.
104 dc.SetMapMode(wx.MM_POINTS)
105
106 dc.SetTextForeground("red")
107 dc.SetFont(wx.Font(20, wx.SWISS, wx.NORMAL, wx.BOLD))
108 dc.DrawText(self.lines, 50, 100)
109
110 # R, V, B.
111 dc.SetPen(wx.Pen(wx.Colour(255, 20, 5)))
112 dc.SetBrush(wx.Brush(wx.Colour(30, 255, 20)))
113 # x, y, radius.
114 dc.DrawCircle(100, 275, 25)
115 # x, y, width, height.
116 dc.DrawEllipse(100, 275, 75, 50)
117
118 return True
119
120 #-------------------------------------------------------------------------------
121
122 class My_Frame(wx.Frame):
123 """
124 Create a main frame for my application.
125 """
126 def __init__(self, parent, id, title=""):
127 wx.Frame.__init__(self,
128 parent,
129 id,
130 title,
131 size=(600, 350),
132 style=wx.DEFAULT_FRAME_STYLE)
133
134 #------------
135
136 # Simplified init method.
137 self.SetProperties()
138 self.CreateMenu()
139 self.CreateCtrls()
140 self.CreatePrintData()
141 self.BindEvents()
142 self.DoLayout()
143
144 #------------
145
146 self.CenterOnScreen()
147
148 #---------------------------------------------------------------------------
149
150 def SetProperties(self):
151 """
152 Set the main frame properties (title, icon...).
153 """
154
155 frameicon = wx.Icon("Icons/wxWidgets.ico")
156 self.SetIcon(frameicon)
157
158 #------------
159
160 self.SetTitle("Printing test...")
161
162
163 def CreateMenu(self):
164 """
165 Make the frame menus.
166 """
167
168 menub = wx.MenuBar()
169
170 fmenu = wx.Menu()
171 fmenu.Append(wx.ID_PAGE_SETUP, "Page set&up\tCtrl+U")
172 fmenu.Append(wx.ID_PREVIEW, "Print pre&view\tCtrl+V")
173 fmenu.Append(wx.ID_PRINT, "&Print\tCtrl+P")
174 fmenu.AppendSeparator()
175 fmenu.Append(wx.ID_EXIT, "E&xit\tCtrl+X")
176 menub.Append(fmenu, "&File")
177
178 self.SetMenuBar(menub)
179
180
181 def CreateCtrls(self):
182 """
183 Make widgets for my app.
184 """
185
186 font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
187 font.SetWeight(wx.BOLD)
188 font.SetPointSize(10)
189
190 #------------
191
192 # First create the controls.
193 self.panel = wx.Panel(self,
194 id=-1,
195 style=wx.BORDER_THEME|
196 wx.TAB_TRAVERSAL)
197
198 self.text = wx.StaticText(self.panel,
199 id=-1,
200 label="Demonstrating :")
201 self.text.SetFont(font)
202
203 self.info = wx.StaticText(self.panel,
204 id=-1,
205 label="1) Direct printing,\n"
206 "2) Printout class,\n"
207 "3) Preview,\n"
208 "4) Menu,\n"
209 "5) Page setup.")
210 self.info.SetForegroundColour("red")
211 font.SetWeight(wx.NORMAL)
212 self.info.SetFont(font)
213
214 self.tc = wx.TextCtrl(self.panel,
215 id=-1,
216 size=(200, -1),
217 value="Hello, World ! A sample text.")
218
219 self.btnSetup = wx.Button(self.panel,
220 id=wx.ID_PAGE_SETUP,
221 label="Page set&up")
222
223 self.btnPreview = wx.Button(self.panel,
224 id=wx.ID_PREVIEW,
225 label="Print pre&view")
226 self.btnPreview.SetFocus()
227
228 self.btnPrint = wx.Button(self.panel,
229 id=wx.ID_PRINT,
230 label="&Print")
231
232 self.btnClose = wx.Button(self.panel,
233 id=wx.ID_CLOSE,
234 label="E&xit")
235
236
237 def CreatePrintData(self):
238 """
239 Create printing data.
240 """
241
242 self.printdata = wx.PrintData()
243
244 self.printdata.SetPrinterName('')
245 self.printdata.SetOrientation(wx.PORTRAIT)
246 self.printdata.SetPaperId(wx.PAPER_A4)
247 self.printdata.SetQuality(wx.PRINT_QUALITY_DRAFT)
248 # Black and white printing if False.
249 self.printdata.SetColour(True)
250 self.printdata.SetNoCopies(1)
251 self.printdata.SetCollate(True)
252 # self.printData.SetPrintMode(wx.PRINT_MODE_PRINTER)
253
254
255 def BindEvents(self):
256 """
257 Bind all the events related to my application.
258 """
259
260 # Bind some menu events to an events handler.
261 self.Bind(wx.EVT_MENU, self.OnBtnPageSetup, id=wx.ID_PAGE_SETUP)
262 self.Bind(wx.EVT_MENU, self.OnBtnPreview, id=wx.ID_PREVIEW)
263 self.Bind(wx.EVT_MENU, self.OnBtnPrint, id=wx.ID_PRINT)
264 self.Bind(wx.EVT_MENU, self.OnBtnClose, id=wx.ID_EXIT)
265
266 # Bind the close event to an event handler.
267 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
268
269 # Bind some buttons events to an events handler.
270 self.Bind(wx.EVT_BUTTON, self.OnBtnPageSetup, self.btnSetup)
271 self.Bind(wx.EVT_BUTTON, self.OnBtnPreview, self.btnPreview)
272 self.Bind(wx.EVT_BUTTON, self.OnBtnPrint, self.btnPrint)
273 self.Bind(wx.EVT_BUTTON, self.OnBtnClose, self.btnClose)
274
275
276 def DoLayout(self):
277 """
278 Manage widgets Layout.
279 """
280
281 # MainSizer is the top-level one that manages everything.
282 mainSizer = wx.BoxSizer(wx.VERTICAL)
283
284 #------------
285
286 hBox1 = wx.BoxSizer(wx.HORIZONTAL)
287 hBox1.Add(self.info, 0, wx.ALL, 15)
288
289 #------------
290
291 hBox2 = wx.BoxSizer(wx.HORIZONTAL)
292 hBox2.Add(self.btnSetup, 0, wx.ALL, 10)
293 hBox2.Add(self.btnPreview, 0, wx.ALL, 10)
294 hBox2.Add(self.btnPrint, 0, wx.ALL, 10)
295 hBox2.Add(self.btnClose, 0, wx.ALL, 10)
296
297 #------------
298
299 mainSizer.Add(self.text, 0, wx.ALL, 10)
300 mainSizer.Add(wx.StaticLine(self.panel),
301 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5)
302 mainSizer.Add(self.tc, 0, wx.ALL, 15)
303 mainSizer.Add(hBox1, 0, wx.ALL, 5)
304 mainSizer.Add(hBox2, 0, wx.ALL, 5)
305
306 #------------
307
308 # Finally, tell the panel to use the mainSizer for layout.
309 self.panel.SetSizer(mainSizer)
310
311
312 def OnBtnPageSetup(self, event):
313 """
314 Show the PrinterSetup dialog.
315 """
316
317 psdd = wx.PageSetupDialogData(self.printdata)
318
319 psdd.EnablePrinter(True)
320 # psdd.CalculatePaperSizeFromId()
321
322 #------------
323
324 dlg = wx.PageSetupDialog(self, psdd)
325 dlg.ShowModal()
326
327 #------------
328
329 # This makes a copy of the wx.PrintData instead of just saving
330 # a reference to the one inside the PrintDialogData that will
331 # be destroyed when the dialog is destroyed
332 self.printdata = wx.PrintData(dlg.GetPageSetupData().GetPrintData())
333
334 dlg.Destroy()
335
336
337 def OnBtnPreview(self, event):
338 """
339 Show the print preview.
340 """
341
342 text = self.tc.GetValue()
343
344 #------------
345
346 data = wx.PrintDialogData(self.printdata)
347
348 printout1 = My_Printout(text, "- My printing object")
349 printout2 = My_Printout(text, "- My printing object")
350
351 printPreview = wx.PrintPreview(printout1, printout2, data)
352
353 # Initial zoom value.
354 if "__WXMAC__" in wx.PlatformInfo:
355 printPreview.SetZoom(50)
356 else:
357 printPreview.SetZoom(35)
358
359 if not printPreview.IsOk():
360 wx.MessageBox(("There was a problem printing.\nPerhaps "\
361 "your current printer is \nnot "\
362 "set correctly ?"),
363 ("Printing"),
364 wx.OK)
365 return
366
367 else:
368 previewFrame = wx.PreviewFrame(printPreview, None, "Print preview")
369 previewFrame.Initialize()
370 previewFrame.SetPosition(self.GetPosition())
371 previewFrame.SetSize(self.GetSize())
372 # Or full screen :
373 # previewFrame.Maximize()
374 previewFrame.Show(True)
375 previewFrame.Layout()
376
377
378 def OnBtnPrint(self, event):
379 """
380 Prints the document.
381 """
382
383 text = self.tc.GetValue()
384
385 #------------
386
387 pdd = wx.PrintDialogData(self.printdata)
388 pdd.SetPrintData(self.printdata)
389 pdd.SetMinPage(1)
390 pdd.SetMaxPage(1)
391 pdd.SetFromPage(1)
392 pdd.SetToPage(1)
393 pdd.SetPrintToFile(False)
394 # pdd.SetSetupDialog(False)
395 # pdd.EnableSelection(True)
396 # pdd.EnablePrintToFile(True)
397 # pdd.EnablePageNumbers(True)
398 # pdd.SetAllPages(True)
399
400 #------------
401
402 printer = wx.Printer(pdd)
403
404 myPrintout = My_Printout(text, "- My printing object")
405
406 if not printer.Print(self, myPrintout, True):
407 wx.MessageBox(("There was a problem printing.\nPerhaps "\
408 "your current printer is \nnot "\
409 "set correctly ?"),
410 ("Printing"),
411 wx.OK)
412 return
413
414 else:
415 self.printData = wx.PrintData(printer.GetPrintDialogData().GetPrintData())
416 myPrintout.Destroy()
417
418
419 def OnBtnClose(self, event):
420 """
421 ...
422 """
423
424 self.Close(True)
425
426
427 def OnCloseWindow(self, event):
428 """
429 ...
430 """
431
432 self.Destroy()
433
434 #-------------------------------------------------------------------------------
435
436 class My_App(wx.App):
437 """
438 ...
439 """
440 def OnInit(self):
441
442 #------------
443
444 self.locale = wx.Locale(wx.LANGUAGE_ENGLISH)
445
446 #------------
447
448 frame = My_Frame(None, id=-1)
449 self.SetTopWindow(frame)
450 frame.Show(True)
451
452 return True
453
454
455 #-------------------------------------------------------------------------------
456
457 def main():
458 app = My_App(False)
459 app.MainLoop()
460
461 #-------------------------------------------------------------------------------
462
463 if __name__ == "__main__" :
464 main()
Canvas and printout class
1 # sample_three.py
2
3 import sys
4 import os
5 import platform
6 import time
7 import wx
8
9 # class My_Canvas
10 # class My_Printout
11 # class My_Frame
12 # class My_App
13
14 # There are two different approaches to drawing, buffered or direct.
15 # This sample shows both approaches so you can easily compare and
16 # contrast the two by changing this value :
17 BUFFERED = 1
18
19 #-------------------------------------------------------------------------------
20
21 if os.name == "posix":
22 print("\nPlatform : UNIX - Linux")
23 elif os.name in ['nt', 'dos', 'ce']:
24 print("\nPlatform : Windows")
25 else:
26 print("\nPlatform : ", platform.system())
27
28 #-------------------------------------------------------------------------------
29
30 class My_Canvas(wx.ScrolledWindow):
31 """
32 ...
33 """
34 def __init__(self, parent, id=-1, size=wx.DefaultSize):
35 wx.ScrolledWindow.__init__(self,
36 parent,
37 id,
38 pos=(0, 0),
39 size=size,
40 style=wx.SUNKEN_BORDER)
41
42 #------------
43
44 self.maxWidth = 1000
45 self.maxHeight = 1000
46 self.x = self.y = 0
47 self.drawing = False
48
49 #------------
50
51 self.SetVirtualSize((self.maxWidth, self.maxHeight))
52 self.SetScrollRate(30, 30)
53
54 #------------
55
56 if BUFFERED:
57 # Initialize the buffer bitmap. No real DC is needed at this point
58 self.buffer = wx.Bitmap(self.maxWidth, self.maxHeight)
59 dc = wx.BufferedDC(None, self.buffer)
60 dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
61 dc.Clear()
62 self.DoDrawing(dc)
63
64 #------------
65
66 # Bind a paint event to an events handler
67 self.Bind(wx.EVT_PAINT, self.OnPaint)
68
69 #---------------------------------------------------------------------------
70
71 def GetWidth(self):
72 """
73 ...
74 """
75
76 return self.maxWidth
77
78
79 def GetHeight(self):
80 """
81 ...
82 """
83
84 return self.maxHeight
85
86
87 def OnPaint(self, event):
88 """
89 ...
90 """
91
92 if BUFFERED:
93 # Create a buffered paint DC. It will create the real
94 # wx.PaintDC and then blit the bitmap to it when dc is
95 # deleted. Since we don't need to draw anything else
96 # here that's all there is to it.
97 dc = wx.BufferedPaintDC(self, self.buffer, wx.BUFFER_VIRTUAL_AREA)
98 else:
99 dc = wx.PaintDC(self)
100 self.PrepareDC(dc)
101 # Since we're not buffering in this case, we have to
102 # (re)paint the all the contents of the window, which can
103 # be potentially time consuming and flickery depending on
104 # what is being drawn and how much of it there is.
105 self.DoDrawing(dc)
106
107
108 def DoDrawing(self, dc, printing=False):
109 """
110 ...
111 """
112
113 # Draw.
114 pen = wx.Pen("BLACK", 4, wx.SOLID)
115
116 dc.SetPen(wx.TRANSPARENT_PEN)
117 dc.SetBrush(wx.Brush("#e0f0f0"))
118
119 for i in range(56, 784, 56):
120 dc.DrawRectangle(0, i, 794, 28)
121
122 pen.SetCap(wx.CAP_BUTT)
123 dc.SetPen(pen)
124 dc.DrawLine(397, 56, 397, 756)
125
126 pen.SetCap(wx.CAP_BUTT)
127 dc.SetPen(pen)
128 dc.DrawLine(0, 756, 794, 756)
129
130 pen.SetCap(wx.CAP_BUTT)
131 dc.SetPen(pen)
132 dc.DrawLine(0, 56, 794, 56)
133
134 dc.SetTextForeground("BLACK")
135 dc.SetFont(wx.Font(24, wx.DEFAULT, wx.NORMAL, wx.BOLD))
136 dc.DrawText("Python", 15, 8)
137
138 pen.SetJoin(wx.JOIN_MITER)
139 dc.SetPen(pen)
140 dc.SetBrush(wx.TRANSPARENT_BRUSH)
141 dc.DrawRectangle(0, 0, 794, 794)
142
143 dc.SetPen(wx.Pen("RED", 1))
144 dc.DrawRectangle(0, 0, 1000, 1000)
145
146 #-------------------------------------------------------------------------------
147
148 class My_Printout(wx.Printout):
149 """
150 Create a printout.
151 """
152 def __init__(self, canvas, text, title):
153 wx.Printout.__init__(self, title)
154
155 #------------
156
157 self.canvas = canvas
158 self.lines = text
159
160 #---------------------------------------------------------------------------
161
162 def OnBeginDocument(self, start, end):
163 """
164 ...
165 """
166
167 return super(My_Printout, self).OnBeginDocument(start, end)
168
169
170 def OnEndDocument(self):
171 """
172 ...
173 """
174
175 super(My_Printout, self).OnEndDocument()
176
177
178 def OnBeginPrinting(self):
179 """
180 ...
181 """
182
183 super(My_Printout, self).OnBeginPrinting()
184
185
186 def OnEndPrinting(self):
187 """
188 ...
189 """
190
191 super(My_Printout, self).OnEndPrinting()
192
193
194 def OnPreparePrinting(self):
195 """
196 ...
197 """
198
199 super(My_Printout, self).OnPreparePrinting()
200
201
202 def HasPage(self, page):
203 """
204 ...
205 """
206
207 if page <= 2:
208 return True
209 else:
210 return False
211
212
213 def GetPageInfo(self):
214 """
215 ...
216 """
217
218 return (1, 2, 1, 2)
219
220
221 def OnPrintPage(self, page):
222 """
223 ...
224 """
225
226 dc = self.GetDC()
227
228 # (wx.MM_METRIC) ---> Each logical unit is 1 mm.
229 # (wx.MM_POINTS) ---> Each logical unit is a "printer point" i.e.
230 # dc.SetMapMode(wx.MM_POINTS)
231
232 #------------
233
234 # One possible method of setting scaling factors...
235 maxX = self.canvas.GetWidth()
236 maxY = self.canvas.GetHeight()
237
238 #------------
239
240 # Let's have at least 50 device units margin.
241 marginX = 180
242 marginY = 180
243
244 #------------
245
246 # Add the margin to the graphic size.
247 maxX = maxX + (2 * marginX)
248 maxY = maxY + (2 * marginY)
249
250 #------------
251
252 # Get the size of the DC in pixels.
253 # (w, h) = dc.GetSizeTuple()
254 (w, h) = dc.GetSize()
255
256 # Calculate a suitable scaling factor.
257 scaleX = float(w) / maxX
258 scaleY = float(h) / maxY
259
260 # Use x or y scaling factor, whichever fits on the DC.
261 actualScale = min(scaleX, scaleY)
262
263 # Calculate the position on the DC for centering the graphic.
264 posX = (w - (self.canvas.GetWidth() * actualScale)) / 2.0
265 posY = (h - (self.canvas.GetHeight() * actualScale)) / 2.0
266
267 # Set the scale and origin.
268 dc.SetUserScale(actualScale, actualScale)
269 dc.SetDeviceOrigin(int(posX), int(posY))
270
271 #------------
272
273 self.canvas.DoDrawing(dc, True)
274
275 #------------
276
277 # Draw.
278 dc.SetTextForeground("RED")
279 dc.SetFont(wx.Font(17, wx.DEFAULT, wx.NORMAL, wx.NORMAL))
280 dc.DrawText(self.lines, 6, 57)
281 dc.DrawText(self.lines, 6, 85)
282 dc.DrawText(self.lines, 6, 113)
283 dc.DrawText(self.lines, 6, 141)
284 dc.DrawText(self.lines, 6, 169)
285 dc.DrawText(self.lines, 6, 197)
286
287 dc.SetTextForeground("GRAY")
288 dc.SetFont(wx.Font(32, wx.DEFAULT, wx.NORMAL, wx.BOLD))
289 dc.DrawText(("wxPython sample :"), 0, -150)
290
291 dc.SetTextForeground("BLACK")
292 dc.SetFont(wx.Font(18, wx.DEFAULT, wx.NORMAL, wx.BOLD))
293 dc.DrawText(("Page : %d") % page, int(marginX/2), int(maxY-marginY))
294
295 tm = time.strftime(("Printing %a, %d %b %Y - %Hh%M"))
296
297 dc.SetTextForeground("GRAY")
298 dc.SetFont(wx.Font(16, wx.DEFAULT, wx.NORMAL, wx.NORMAL))
299 dc.DrawText(tm, 10, 764)
300
301 return True
302
303 #-------------------------------------------------------------------------------
304
305 class My_Frame(wx.Frame):
306 """
307 Create a main frame for my application.
308 """
309 def __init__(self, parent, id, title=""):
310 wx.Frame.__init__(self,
311 parent,
312 id,
313 title,
314 size=(600, 367),
315 style=wx.DEFAULT_FRAME_STYLE)
316
317 #------------
318
319 # Simplified init method.
320 self.SetProperties()
321 self.CreateMenu()
322 self.CreateCtrls()
323 self.CreatePrintData()
324 self.BindEvents()
325 self.DoLayout()
326
327 #------------
328
329 self.CenterOnScreen()
330
331 #---------------------------------------------------------------------------
332
333 def SetProperties(self):
334 """
335 Set the main frame properties (title, icon...).
336 """
337
338 frameicon = wx.Icon("Icons/wxWidgets.ico")
339 self.SetIcon(frameicon)
340
341 #------------
342
343 self.SetTitle("Printing test...")
344
345
346 def CreateMenu(self):
347 """
348 Make the frame menus.
349 """
350
351 menub = wx.MenuBar()
352
353 fmenu = wx.Menu()
354 fmenu.Append(wx.ID_PAGE_SETUP, "Page set&up\tCtrl+U")
355 fmenu.Append(wx.ID_PREVIEW, "Print pre&view\tCtrl+V")
356 fmenu.Append(wx.ID_PRINT, "&Print\tCtrl+P")
357 fmenu.AppendSeparator()
358 fmenu.Append(wx.ID_EXIT, "E&xit\tCtrl+X")
359 menub.Append(fmenu, "&File")
360
361 self.SetMenuBar(menub)
362
363
364 def CreateCtrls(self):
365 """
366 Make widgets for my app.
367 """
368
369 font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
370 font.SetWeight(wx.BOLD)
371 font.SetPointSize(10)
372
373 #------------
374
375 # First create the controls.
376 self.panel = wx.Panel(self,
377 id=-1,
378 style=wx.BORDER_THEME|
379 wx.TAB_TRAVERSAL)
380
381 self.text = wx.StaticText(self.panel,
382 id=-1,
383 label="Demonstrating :")
384 self.text.SetFont(font)
385
386 self.info = wx.StaticText(self.panel,
387 id=-1,
388 label="1) Direct printing,\n"
389 "2) Printout class,\n"
390 "3) Canvas class,\n"
391 "4) Preview,\n"
392 "5) Menu,\n"
393 "6) Page setup.")
394 self.info.SetForegroundColour("red")
395 font.SetWeight(wx.NORMAL)
396 self.info.SetFont(font)
397
398 self.tc = wx.TextCtrl(self.panel,
399 id=-1,
400 size=(200, -1),
401 value="Hello, World ! A sample text.")
402
403 self.canvas = My_Canvas(self.panel, size=(0, 0))
404
405 self.btnSetup = wx.Button(self.panel,
406 id=wx.ID_PAGE_SETUP,
407 label="Page set&up")
408
409 self.btnPreview = wx.Button(self.panel,
410 id=wx.ID_PREVIEW,
411 label="Print pre&view")
412 self.btnPreview.SetFocus()
413
414 self.btnPrint = wx.Button(self.panel,
415 id=wx.ID_PRINT,
416 label="&Print")
417
418 self.btnClose = wx.Button(self.panel,
419 id=wx.ID_CLOSE,
420 label="E&xit")
421
422
423 def CreatePrintData(self):
424 """
425 Create printing data.
426 """
427
428 self.printdata = wx.PrintData()
429
430 self.printdata.SetPrinterName('')
431 self.printdata.SetOrientation(wx.PORTRAIT)
432 self.printdata.SetPaperId(wx.PAPER_A4)
433 self.printdata.SetQuality(wx.PRINT_QUALITY_DRAFT)
434 # Black and white printing if False.
435 self.printdata.SetColour(True)
436 self.printdata.SetNoCopies(1)
437 self.printdata.SetCollate(True)
438 # self.printData.SetPrintMode(wx.PRINT_MODE_PRINTER)
439
440
441 def BindEvents(self):
442 """
443 Bind all the events related to my application.
444 """
445
446 # Bind some menu events to an events handler.
447 self.Bind(wx.EVT_MENU, self.OnBtnPageSetup, id=wx.ID_PAGE_SETUP)
448 self.Bind(wx.EVT_MENU, self.OnBtnPreview, id=wx.ID_PREVIEW)
449 self.Bind(wx.EVT_MENU, self.OnBtnPrint, id=wx.ID_PRINT)
450 self.Bind(wx.EVT_MENU, self.OnBtnClose, id=wx.ID_EXIT)
451
452 # Bind the close event to an event handler.
453 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
454
455 # Bind some buttons events to an events handler.
456 self.Bind(wx.EVT_BUTTON, self.OnBtnPageSetup, self.btnSetup)
457 self.Bind(wx.EVT_BUTTON, self.OnBtnPreview, self.btnPreview)
458 self.Bind(wx.EVT_BUTTON, self.OnBtnPrint, self.btnPrint)
459 self.Bind(wx.EVT_BUTTON, self.OnBtnClose, self.btnClose)
460
461
462 def DoLayout(self):
463 """
464 Manage widgets Layout.
465 """
466
467 # MainSizer is the top-level one that manages everything.
468 mainSizer = wx.BoxSizer(wx.VERTICAL)
469
470 #------------
471
472 hBox1 = wx.BoxSizer(wx.HORIZONTAL)
473 hBox1.Add(self.info, 0, wx.ALL, 15)
474
475 #------------
476
477 hBox2 = wx.BoxSizer(wx.HORIZONTAL)
478 hBox2.Add(self.btnSetup, 0, wx.ALL, 10)
479 hBox2.Add(self.btnPreview, 0, wx.ALL, 10)
480 hBox2.Add(self.btnPrint, 0, wx.ALL, 10)
481 hBox2.Add(self.btnClose, 0, wx.ALL, 10)
482
483 #------------
484
485 mainSizer.Add(self.text, 0, wx.ALL, 10)
486 mainSizer.Add(wx.StaticLine(self.panel),
487 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5)
488 mainSizer.Add(self.tc, 0, wx.ALL, 15)
489 mainSizer.Add(hBox1, 0, wx.ALL, 5)
490 mainSizer.Add(hBox2, 0, wx.ALL, 5)
491
492 #------------
493
494 # Finally, tell the panel to use the mainSizer for layout.
495 self.panel.SetSizer(mainSizer)
496
497
498 def OnBtnPageSetup(self, event):
499 """
500 Show the PrinterSetup dialog.
501 """
502
503 psdd = wx.PageSetupDialogData(self.printdata)
504
505 psdd.EnablePrinter(True)
506 # psdd.CalculatePaperSizeFromId()
507
508 #------------
509
510 dlg = wx.PageSetupDialog(self, psdd)
511 dlg.ShowModal()
512
513 #------------
514
515 # This makes a copy of the wx.PrintData instead of just saving
516 # a reference to the one inside the PrintDialogData that will
517 # be destroyed when the dialog is destroyed
518 self.printdata = wx.PrintData(dlg.GetPageSetupData().GetPrintData())
519
520 dlg.Destroy()
521
522
523 def OnBtnPreview(self, event):
524 """
525 Show the print preview.
526 """
527
528 text = self.tc.GetValue()
529
530 #------------
531
532 data = wx.PrintDialogData(self.printdata)
533
534 printout1 = My_Printout(self.canvas, text, "- My printing object")
535 printout2 = My_Printout(self.canvas, text, "- My printing object")
536
537 printPreview = wx.PrintPreview(printout1, printout2, data)
538
539 # Initial zoom value.
540 if "__WXMAC__" in wx.PlatformInfo:
541 printPreview.SetZoom(50)
542 else:
543 printPreview.SetZoom(35)
544
545 if not printPreview.IsOk():
546 wx.MessageBox(("There was a problem printing.\nPerhaps "\
547 "your current printer is \nnot "\
548 "set correctly ?"),
549 ("Printing"),
550 wx.OK)
551 return
552
553 else:
554 previewFrame = wx.PreviewFrame(printPreview, None, "Print preview")
555 previewFrame.Initialize()
556 previewFrame.SetPosition(self.GetPosition())
557 previewFrame.SetSize(self.GetSize())
558 # Or full screen :
559 # previewFrame.Maximize()
560 previewFrame.Show(True)
561 previewFrame.Layout()
562
563
564 def OnBtnPrint(self, event):
565 """
566 Prints the document.
567 """
568
569 text = self.tc.GetValue()
570
571 #------------
572
573 pdd = wx.PrintDialogData(self.printdata)
574 pdd.SetPrintData(self.printdata)
575 pdd.SetMinPage(1)
576 pdd.SetMaxPage(1)
577 pdd.SetFromPage(1)
578 pdd.SetToPage(1)
579 pdd.SetPrintToFile(False)
580 # pdd.SetSetupDialog(False)
581 # pdd.EnableSelection(True)
582 # pdd.EnablePrintToFile(True)
583 # pdd.EnablePageNumbers(True)
584 # pdd.SetAllPages(True)
585
586 #------------
587
588 printer = wx.Printer(pdd)
589
590 myPrintout = My_Printout(self.canvas, text, "- My printing object")
591
592 if not printer.Print(self, myPrintout, True):
593 wx.MessageBox(("There was a problem printing.\nPerhaps "\
594 "your current printer is \nnot "\
595 "set correctly ?"),
596 ("Printing"),
597 wx.OK)
598 return
599
600 else:
601 self.printData = wx.PrintData(printer.GetPrintDialogData().GetPrintData())
602 myPrintout.Destroy()
603
604
605 def OnBtnClose(self, event):
606 """
607 ...
608 """
609
610 self.Close(True)
611
612
613 def OnCloseWindow(self, event):
614 """
615 ...
616 """
617
618 self.Destroy()
619
620 #-------------------------------------------------------------------------------
621
622 class My_App(wx.App):
623 """
624 ...
625 """
626 def OnInit(self):
627
628 #------------
629
630 self.locale = wx.Locale(wx.LANGUAGE_ENGLISH)
631
632 #------------
633
634 frame = My_Frame(None, id=-1)
635 self.SetTopWindow(frame)
636 frame.Show(True)
637
638 return True
639
640 #-------------------------------------------------------------------------------
641
642 def main():
643 app = My_App(False)
644 app.MainLoop()
645
646 #-------------------------------------------------------------------------------
647
648 if __name__ == "__main__" :
649 main()
Download source
Additional Information
Link :
https://wiki.wxpython.org/MoreCommentsOnPrinting
https://wiki.wxpython.org/PrintingWithReportGenerators
http://www.blog.pythonlibrary.org/2010/05/15/manipulating-pdfs-with-python-and-pypdf/
https://www.blog.pythonlibrary.org/2010/02/14/python-windows-and-printers/
- - - - -
https://wiki.wxpython.org/TitleIndex
Thanks to
Lorne White, Jeff Grimmett, Vernon Cole, Robin Dunn, Andy Robinson / Robin Becker / The ReportLab team, David Hughe (PDFViewer), Ruikai Liu / Jorj X. McKie (PyMuPDF), Cody Precord, Mike Driscoll, Pascal Faut., Dietmar Schwertberger, Chris Barker, the wxPython community...
Thanks also to all known contributors or anonymous that I forgot.
And finally, congratulations to the many forums and blogs for all the available examples and the help which is the strength of wxPython.
About this page
Date (d/m/y) Person (bot) Comments :
00/00/00 - Sean McKay (originally Created).
10/10/18 - Ecco (Updated page and published examples for wxPython Phoenix).
Comments
- blah, blah, blah....