I’m using the PrintFramework.py demo example to print some line charts but I have some problems:
If I set the self.canvas.getWidth() and self.canvas.getHeight() myself, I see a preview but the 2 plots are splitted on two pages. How I can put them one under the other?
···
import wx
BUFFERED = 1
class MyCanvas(wx.ScrolledWindow):
def init(self, parent, id = -1, size = wx.DefaultSize):
wx.ScrolledWindow.init(self, parent, id, (0, 0), size=size, style=wx.SUNKEN_BORDER)
self.lines = []
self.maxWidth = 1000
self.maxHeight = 1000
self.x = self.y = 0
self.curLine = []
self.drawing = False
self.SetBackgroundColour(“WHITE”)
self.SetVirtualSize((self.maxWidth, self.maxHeight))
self.SetScrollRate(20,20)
if BUFFERED:
self.buffer = wx.EmptyBitmap(self.maxWidth, self.maxHeight)
dc = wx.BufferedDC(None, self.buffer)
dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
dc.Clear()
y = 100
for i in range(2):
self.DoDrawing(dc, y = y)
y = y + 220
self.Bind(wx.EVT_PAINT, self.OnPaint)
def OnPaint(self, event):
if BUFFERED:
dc = wx.BufferedPaintDC(self, self.buffer, wx.BUFFER_VIRTUAL_AREA)
else:
dc = wx.PaintDC(self)
self.PrepareDC(dc)
self.DoDrawing(dc, y = 100)
def DoDrawing(self, dc, y, printing=False):
dc.BeginDrawing()
dc.SetPen(wx.Pen('BLACK'))
x = 100 # move plot left and right
#y = 100 # move plot up and down
length = 900
hight = 200
dc.DrawRectangle(x, y, length, hight+1)
lst = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (15, 16), (16, 17), (17, 18)]
final_lst = []
for i in lst:
coord1 = i[0]*length/len(lst)
coord2 = -i[1]*150/21
final_lst.append((coord1, coord2))
dc.SetPen(wx.Pen('RED', 2))
dc.DrawLines(final_lst, x+1, y+200)
dc.EndDrawing()
class MyPrintout(wx.Printout):
def init(self, canvas):
wx.Printout.init(self)
self.canvas = canvas
def OnBeginDocument(self, start, end):
return super(MyPrintout, self).OnBeginDocument(start, end)
def OnEndDocument(self):
super(MyPrintout, self).OnEndDocument()
def OnBeginPrinting(self):
super(MyPrintout, self).OnBeginPrinting()
def OnEndPrinting(self):
super(MyPrintout, self).OnEndPrinting()
def OnPreparePrinting(self):
super(MyPrintout, self).OnPreparePrinting()
def HasPage(self, page):
if page <= 2:
return True
else:
return False
def GetPageInfo(self):
return (1, 2, 1, 2)
def OnPrintPage(self, page):
dc = self.GetDC()
#-------------------------------------------
# One possible method of setting scaling factors…
maxX = self.canvas.getWidth()
maxY = self.canvas.getHeight()
Let’s have at least 50 device units margin
marginX = 50
marginY = 50
Add the margin to the graphic size
maxX = maxX + (2 * marginX)
maxY = maxY + (2 * marginY)
Get the size of the DC in pixels
(w, h) = dc.GetSizeTuple()
Calculate a suitable scaling factor
scaleX = float(w) / maxX
scaleY = float(h) / maxY
Use x or y scaling factor, whichever fits on the DC
actualScale = min(scaleX, scaleY)
Calculate the position on the DC for centering the graphic
posX = (w - (self.canvas.getWidth() * actualScale)) / 2.0
posY = (h - (self.canvas.getHeight() * actualScale)) / 2.0
Set the scale and origin
dc.SetUserScale(actualScale, actualScale)
dc.SetDeviceOrigin(int(posX), int(posY))
#-------------------------------------------
self.canvas.DoDrawing(dc, True)
dc.DrawText(“Page: %d” % page, marginX/2, maxY-marginY)
return True
class MyHelpFrame(wx.Frame):
def init(self):
wx.Frame.init(self, None, -1, “Help”, size=(1100, 800))
self.printData = wx.PrintData()
self.printData.SetPaperId(wx.PAPER_LETTER)
self.printData.SetPrintMode(wx.PRINT_MODE_PRINTER)
self.printData.SetOrientation(wx.LANDSCAPE)
self.box = wx.BoxSizer(wx.VERTICAL)
self.canvas = MyCanvas(self)
self.box.Add(self.canvas, 1, wx.GROW)
self.SetAutoLayout(True)
self.SetSizer(self.box)
self.build_menu()
def build_menu(self):
# Create Menu Bar
menuBar = wx.MenuBar()
# Create Menu1 from left
menu1 = wx.Menu()
menu1.Append(101, "Preview")
# Append all Menus
menuBar.Append(menu1, "Preview")
# # Bind all Menus
self.Bind(wx.EVT_MENU, self.OnPrintPreview, id=101)
self.SetMenuBar(menuBar)
def OnPrintPreview(self, event):
data = wx.PrintDialogData(self.printData)
printout = MyPrintout(self.canvas)
printout2 = MyPrintout(self.canvas)
self.preview = wx.PrintPreview(printout, printout2, data)
if not self.preview.Ok():
return
pfrm = wx.PreviewFrame(self.preview, self, “This is a print preview”)
pfrm.Initialize()
pfrm.SetPosition(self.GetPosition())
pfrm.SetSize(self.GetSize())
pfrm.Show(True)
if name == ‘main’:
app = wx.PySimpleApp()
frame = MyHelpFrame()
frame.Show(True)
app.MainLoop()
import wx
import test
class MyPrintout(wx.Printout):
def init(self, canvas):
wx.Printout.init(self)
self.canvas = canvas
def OnBeginDocument(self, start, end):
return super(MyPrintout, self).OnBeginDocument(start, end)
def OnEndDocument(self):
super(MyPrintout, self).OnEndDocument()
def OnBeginPrinting(self):
super(MyPrintout, self).OnBeginPrinting()
def OnEndPrinting(self):
super(MyPrintout, self).OnEndPrinting()
def OnPreparePrinting(self):
super(MyPrintout, self).OnPreparePrinting()
def HasPage(self, page):
if page <= 2:
return True
else:
return False
def GetPageInfo(self):
return (1, 2, 1, 2)
def OnPrintPage(self, page):
dc = self.GetDC()
#-------------------------------------------
# One possible method of setting scaling factors…
maxX = self.canvas.getWidth()
maxY = self.canvas.getHeight()
Let’s have at least 50 device units margin
marginX = 50
marginY = 50
Add the margin to the graphic size
maxX = maxX + (2 * marginX)
maxY = maxY + (2 * marginY)
Get the size of the DC in pixels
(w, h) = dc.GetSizeTuple()
Calculate a suitable scaling factor
scaleX = float(w) / maxX
scaleY = float(h) / maxY
Use x or y scaling factor, whichever fits on the DC
actualScale = min(scaleX, scaleY)
Calculate the position on the DC for centering the graphic
posX = (w - (self.canvas.getWidth() * actualScale)) / 2.0
posY = (h - (self.canvas.getHeight() * actualScale)) / 2.0
Set the scale and origin
dc.SetUserScale(actualScale, actualScale)
dc.SetDeviceOrigin(int(posX), int(posY))
#-------------------------------------------
self.canvas.DoDrawing(dc, True)
dc.DrawText(“Page: %d” % page, marginX/2, maxY-marginY)
return True
#----------------------------------------------------------------------
class TestPrintPanel(wx.Panel):
def init(self, parent, frame):
wx.Panel.init(self, parent, -1)
self.frame = frame
self.printData = wx.PrintData()
self.printData.SetPaperId(wx.PAPER_LETTER)
self.printData.SetPrintMode(wx.PRINT_MODE_PRINTER)
self.box = wx.BoxSizer(wx.VERTICAL)
self.canvas = ScrolledWindow.MyCanvas(self)
self.box.Add(self.canvas, 1, wx.GROW)
subbox = wx.BoxSizer(wx.HORIZONTAL)
btn = wx.Button(self, -1, “Page Setup”)
self.Bind(wx.EVT_BUTTON, self.OnPageSetup, btn)
subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
btn = wx.Button(self, -1, “Print Preview”)
self.Bind(wx.EVT_BUTTON, self.OnPrintPreview, btn)
subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
btn = wx.Button(self, -1, “Print”)
self.Bind(wx.EVT_BUTTON, self.OnDoPrint, btn)
subbox.Add(btn, 1, wx.GROW | wx.ALL, 2)
self.box.Add(subbox, 0, wx.GROW)
self.SetAutoLayout(True)
self.SetSizer(self.box)
def OnPageSetup(self, evt):
psdd = wx.PageSetupDialogData(self.printData)
psdd.CalculatePaperSizeFromId()
dlg = wx.PageSetupDialog(self, psdd)
dlg.ShowModal()
this makes a copy of the wx.PrintData instead of just saving
# a reference to the one inside the PrintDialogData that will
# be destroyed when the dialog is destroyed
self.printData = wx.PrintData( dlg.GetPageSetupData().GetPrintData() )
dlg.Destroy()
def OnPrintPreview(self, event):
data = wx.PrintDialogData(self.printData)
printout = MyPrintout(self.canvas)
printout2 = MyPrintout(self.canvas)
self.preview = wx.PrintPreview(printout, printout2, data)
if not self.preview.Ok():
self.log.WriteText(“Houston, we have a problem…\n”)
return
pfrm = wx.PreviewFrame(self.preview, self.frame, “This is a print preview”)
pfrm.Initialize()
pfrm.SetPosition(self.frame.GetPosition())
pfrm.SetSize(self.frame.GetSize())
pfrm.Show(True)
def OnDoPrint(self, event):
pdd = wx.PrintDialogData(self.printData)
pdd.SetToPage(2)
printer = wx.Printer(pdd)
printout = MyPrintout(self.canvas)
if not printer.Print(self.frame, printout, True):
wx.MessageBox(“There was a problem printing.\nPerhaps your current printer is not set correctly?”, “Printing”, wx.OK)
else:
self.printData = wx.PrintData( printer.GetPrintDialogData().GetPrintData() )
printout.Destroy()
class MyHelpFrame(wx.Frame):
def init(self):
wx.Frame.init(self, None, -1, “Help”, size=(1100, 800))
self.canvas = TestPrintPanel(self)
if name == ‘main’:
app = wx.PySimpleApp()
frame = MyHelpFrame()
frame.Show(True)
app.MainLoop()