[wxPython] wxPrintout, How to print a text?

161 views
Skip to first unread message

Jean-Michel Fauth

unread,
Jan 26, 2002, 10:47:03 PM1/26/02
to wxpytho...@lists.wxwindows.org
Hi All,

I'm moving slowly from vb to python/wxPython :-), but I'am completely lost
with wxPrintout when it comes to print (send to the printer) a text. (text
== long string with newline chars that covers more than one page).
I can print nice plots (charts and single line texts) on a single page with
success, but I'am unable to print a text like "1\n2\n3\n ...98\n99\n". The
PrintFramework.py of the demo does not help to much and I did not find a
good/simple example on the net and in the archives (except the printable
text
control, that I find quite complicate).
Below the code of a simple application.
Questions: 1) What is the code in DoPrint() in order to print the string
named txt. To be simple let's forget the margins.
2) Is there a way to send some text to the printer without using wxPrintout?

#-------------------------------------------------------------------
# PrintNum.py
#-------------------------------------------------------------------

from wxPython.wx import *

#-------------------------------------------------------------------

def DoPrint(dc, dcleft, dctop, dcwidth, dcheight):

dc.BeginDrawing()

# How do I print a \n ?
# How do I start a new page if necessara ?

dc.EndDrawing()

#----------------------------------------------------------------------

class MyPrintout(wxPrintout):

def __init__(self):
wxPrintout.__init__(self)

def OnBeginDocument(self, start, end):
return self.base_OnBeginDocument(start, end)

def OnEndDocument(self):
self.base_OnEndDocument()

def OnBeginPrinting(self):
self.base_OnBeginPrinting()

def OnEndPrinting(self):
self.base_OnEndPrinting()

def OnPreparePrinting(self):
self.base_OnPreparePrinting()

def HasPage(self, page):
if page < 10:
return true
else:
return false

def GetPageInfo(self):
return (0, 10, 1, 32000)

def OnPrintPage(self, page):
dc = self.GetDC()
si = dc.GetSize()
DoPrint(dc, 0, 0, si[0], si[1])
return true

#----------------------------------------------------------------------

class MyPanel(wxPanel):

def __init__(self, parent, id):
wxPanel.__init__(self, parent, id, wxDefaultPosition, wxDefaultSize)
self.parent = parent

self.printdata = wxPrintData()

b1 = wxButton(self, 1001, "Close me", wxPoint(20, 10),
wxDefaultSize)
EVT_BUTTON(self, 1001, self.OnClick1)

b2 = wxButton(self, 1002, "print preview", wxPoint(20, 40),
wxDefaultSize)
EVT_BUTTON(self, 1002, self.OnClick2)

b3 = wxButton(self, 1003, "print", wxPoint(20, 70), wxDefaultSize)
EVT_BUTTON(self, 1003, self.OnClick3)

#Quit application --------------------------
def OnClick1(self, event):
self.parent.Destroy()

#Preview -------------------------------------
def OnClick2(self, event):
printout, printout2 = MyPrintout(), MyPrintout()
printpreview = wxPrintPreview(printout, printout2, self.printdata)
if not printpreview.Ok(): return 'Preview problem'
printpreview.SetZoom(50)
#prwview frame == parent frame
pos, size = self.parent.GetPosition(), self.parent.GetSize()
previewframe = wxPreviewFrame(printpreview, self.parent, "Print
preview", pos, size)
previewframe.Initialize()
ret = previewframe.Show(TRUE)

#Print to printer -------------------------------
def OnClick3(self, event):
printdialogdata = wxPrintDialogData()
printdialogdata.SetPrintData(self.printdata)
printer = wxPrinter(printdialogdata)
printout = MyPrintout()
ret = printer.Print(self.parent, printout, false)
if not ret:
print "Printer problem..."
printout.Destroy()

#-------------------------------------------------------------------

class MyFrame(wxFrame):
def __init__(self, parent, id):
wxFrame.__init__(self, parent, id, "TestPrint", wxPoint(100, 10),
wxSize(800, 600))
panel = MyPanel(self, -1)

EVT_CLOSE(self, self.OnCloseWindow)

def OnCloseWindow(self, event):
self.Destroy()

#-------------------------------------------------------------------

class MyApp(wxApp):
def OnInit(self):
frame = MyFrame(NULL, -1)
frame.Show(true)
self.SetTopWindow(frame)
return true

#-------------------------------------------------------------------

def main():
print 'main is running...'
app = MyApp(0)
app.MainLoop()

#-------------------------------------------------------------------

if __name__ == "__main__" :
#txt is global
txt = ''
for i in range(100):
txt = txt + str(i) + '\n'
#~ print txt
main()

#eof-------------------------------------------------------------------


Thank you

Grzegorz Makarewicz

unread,
Jan 27, 2002, 5:40:04 PM1/27/02
to wxpytho...@lists.wxwindows.org
> Questions: 1) What is the code in DoPrint() in order to print the string
> named txt. To be simple let's forget the margins.

def DoPrint(dc, dcleft, dctop, dcwidth, dcheight):
width, height, descent, leading = dc.GetFullTextExtent("M")
x=0
for i in range(10):
dc.DrawText(txt, x, i*height)

In other words, you can draw anything what can be drawn on screen.

> 2) Is there a way to send some text to the printer without using
> wxPrintout?

As always under windows, you can access LPTXX as any normal file, or make it
bit more complicated:

import win32print
flag,desc,name,comment=win32print.EnumPrinters(win32print.PRINTER_ENUM_LOCAL)
hp = win32print.OpenPrinter(name)
info = win32print.GetPrinter(hp)
jobID = win32print.StartDocPrinter(hp,1,('title',info[3],info[10]))
win32print.WritePrinter(hp,open('myfile','rt').read())
win32print.EndDocPrinter(hp)
win32print.ClosePrinter(hp)

mak

Kevin Altis

unread,
Jan 27, 2002, 12:31:04 PM1/27/02
to wxpytho...@lists.wxwindows.org
If you want really simple cross-platform printing I recommend using
wxHtmlEasyPrinting. This is what is going to be used in PythonCard
initially.

ka

> _______________________________________________
> wxpython-users mailing list
> wxpytho...@lists.wxwindows.org
> http://lists.wxwindows.org/mailman/listinfo/wxpython-users
>


Hugo van der Merwe

unread,
Jan 27, 2002, 10:48:03 PM1/27/02
to wxpytho...@lists.wxwindows.org
> def DoPrint(dc, dcleft, dctop, dcwidth, dcheight):
> width, height, descent, leading = dc.GetFullTextExtent("M")
> x=0
> for i in range(10):
> dc.DrawText(txt, x, i*height)
>
> In other words, you can draw anything what can be drawn on screen.

The thing that bothers me atm is setting the UserScale right - I believe
this is necessary? - I used
float(dc.GetSizeTuple()[0]) / dc.GetTextExtent(longestLineIWantToPrint)[0]
as my UserScale, and it seemed to work OK on Linux. But didn't look
right in Windows in print-preview. (I didn't try printing, iirc, or
maybe I printed to pdf and looked at that.)

What bothers me is, yes, a) it didn't work right in Windows, but b) it
seems ugly. I think I want 12pt text to really be 12pt on paper. I saw
some code comparing GetExtents for "X" and setting a scale according to
the ratio between them... I didn't like it very much, but is this the
... *right* thing to do? (I think using a "Canvas" DC and a printer or
preview DC. Ah, yes, it was prnlstwx.py, here's the code it uses, in
OnBeginPrinting:

te1 = dc.GetTextExtent('X')
te2 = self.canvas.GetTextExtent('X')
self.printUserScale = float(te1[1]) / te2[1]

I've not tested it. )

Thanks,
Hugo

Reply all
Reply to author
Forward
0 new messages