[wxPython] wxPrintout, How to print a text?

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

If you want really simple cross-platform printing I recommend using
wxHtmlEasyPrinting. This is what is going to be used in PythonCard
initially.

ka

···

-----Original Message-----
From: wxpython-users-admin@lists.wxwindows.org
[mailto:wxpython-users-admin@lists.wxwindows.org]On Behalf Of
Jean-Michel Fauth
Sent: Sunday, January 27, 2002 3:44 AM
To: wxpython-users@lists.wxwindows.org
Subject: [wxPython] wxPrintout, How to print a text?

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

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

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

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