I have a simple editor with wx.textCtrl MULTILINE as my editing area. Nothing fancy, except I can't do
a "PrintPreview" or a "Print". On the preview it shows a blank screen and the Print prints out a blank piece of paper. The "text" appears on my editor and a "print text" statement prints to my log file so I know GetValue() is grabing it from the TextCtrl. I have copied this almost verbatim from "wxPython IN ACTION" so I don't see why it won't work. Probably something is not set up right, but I cannot see it. No error messages.
-Robin (the other one) This is with Python 2.7.4 and wxPython 2.9 on Windows XP and HP PhotoSmart ptr.

#-------------------------------------------------- under frame (wx.Frame) class -----------------------  
#-----  Background code to see TextCtrl and Bindings ---------------------------------------------------

    self.edit_ctrl = wx.TextCtrl(scrolled_panel, wx.ID_ANY,style=wx.TE_MULTILINE|wx.SUNKEN_BORDER|wx.TE_DONTWRAP)

sizer.Add(self.edit_ctrl, 0, wx.ALL|wx.EXPAND|wx.ALIGN_RIGHT|wx.ADJUST_MINSIZE, 0)
font1 = wx.Font(12, wx.MODERN, wx.NORMAL, wx.NORMAL, False, u'Consolas')
self.edit_ctrl.SetMinSize((1000, 800))

self.PageSetup = wx.MenuItem(self.File,    wx.NewId(), "Page Setup...\tF5", "", wx.ITEM_NORMAL)
self.PrintPreview = wx.MenuItem(self.File, wx.NewId(), "Print Preview...\tF6", "", wx.ITEM_NORMAL)
self.Print = wx.MenuItem(self.File,        wx.NewId(), "&Print...\F7", "", wx.ITEM_NORMAL)

self.Bind(wx.EVT_MENU, self.file_pageSetup,   self.PageSetup) 
self.Bind(wx.EVT_MENU, self.file_printPreview,self.PrintPreview)
self.Bind(wx.EVT_MENU, self.file_print,       self.Print) 

# Printing initialize
self.pdata = wx.PrintData()
    self.margins = (wx.Point(15,15), wx.Point(15,15))

    class MyPrintout(wx.Printout):

   def __init__(self, text, title, margins):
        wx.Printout.__init__(self, title)
        self.lines = text.split('\n')
        self.linesPerPage = 60
        self.margins = margins

   def HasPage(self, page):
        return page <= self.numPages

   def GetPageInfo(self):
        return (1, self.numPages, 1, self.numPages)        

   def OnPreparePrinting(self):
        # calculate the number of pages
        self.numPages = len(self.lines) / self.linesPerPage
        if len(self.lines) % self.linesPerPage != 0:
            self.numPages += 1        

#-------------------------------------------- back under frame (wx.Frame) class ---------------------------     
       # From the Menu "File/Page Setup" allows user to make changes in printer settings
          def file_pageSetup (self, event):
                #print "PageSetup..."
                # This function handles displaying the Page Setup window and retrieving
                # the user selected options.
                #Now for setup...
                data = wx.PageSetupDialogData()
                dlg = wx.PageSetupDialog(self, data) 
                   if dlg.ShowModal() == wx.ID_OK: 
                     data = dlg.GetPageSetupData()
                     self.pdata = wx.PrintData(data.GetPrintData())
                     self.margins = (data.GetMarginTopLeft(), data.GetMarginBottomRight())

    def file_printPreview(self, event):
        global frame
        data = wx.PrintDialogData(self.pdata)
        text = self.edit_ctrl.GetValue() 
        printout1 = MyPrintout(text, "title", self.margins)
        printout2 = None #MyPrintout(text, "title", self.margins)
        preview = wx.PrintPreview(printout1, printout2, data)
        if not preview.Ok():
            wx.MessageBox("Unable to create PrintPreview!", "Error")
            # create the preview frame such that it overlays the app frame
            frame = wx.PreviewFrame(preview, self, "Print Preview",          <===== Displays blank "canvas"

    # From the Menu File/Print will print the contents of the Text_Ctrl to the printer
    def file_print(self, event):
        data = wx.PrintDialogData(self.pdata)
        printer = wx.Printer(data)
        text = self.edit_ctrl.GetValue()
        printout = MyPrintout(text, "title", self.margins)
        useSetupDialog = True
        printer.Print(self, printout, useSetupDialog)        <======================  Prints blank sheet
        if printer.GetLastError() == wx.PRINTER_ERROR:
               wx.MessageBox("There was a problem printing.\n"
                            +"Perhaps your current printer is not set correctly?",
                             "Printing", wx.OK)
            data = printer.GetPrintDialogData()
            self.pdata = wx.PrintData(data.GetPrintData() ) # force a copy

Edited 3 Years Ago by robinlrandall: format

I've given up on rewriting the Printout Framework (4 pages of code) in favor of using HtmlEasyPrinting.
There is a problem with HEP's PrintPreview but I found a decent workaround
self.html_printer=Printer() works for "Print" event but not for PrintPreview. Use the following for PrintPreview instead:
self.html_print=HtmlEasyPrinting(name="Printing", parentWindow=self.TextCtrl)
I believe they are two separate object instances but if you feed them the same text your printer won't care. Also in formatting the text, prepending "<pre>" and appending "</pre> will preserve all spaces.

Here's the code I used that actually worked. I'd be glad to find a better workaround.

import  wx
from    wx.html import HtmlEasyPrinting
class MyFrame=*wx.Frame):
        def __init__ ...

self.TextCtrl=wx.TextCtrl( ... )
#Printer Initialization (create PrintPreview & Print objects)
self.html_printer=Printer()   #Works with PrintPreview
self.html_print=HtmlEasyPrinting(name="Printing", parentWindow=self.TextCtrl) #Works with Print
def GetHtmlText(self,text):
    "Simple conversion of text.  Use a more powerful version"
    text = '<pre>' + text + '</pre>' # Preserve spacing
    html_text = text.replace('\n\n','<P>')     # Paragraphs
    html_text = text.replace('\n', '<BR>')     # Line breaks
    return html_text 

# From the Menu "File/Page Setup" allows user to make changes in printer settings
def file_pageSetup(self, event):

# From the Menu "File/Print Preview" shows how text prints before printing
def file_printPreview(self, event):
    global frame
    text = self.TextCtrl.GetValue()
    doc_name= self.filename
    self.html_printer.PreviewText(self.GetHtmlText(text), doc_name)

# From the Menu "File/Print"  actually prints the text to the printer     
def file_print(self, event):
    global frame
    text = self.TextCtrl.GetValue()
    self.html_print.Print(self.GetHtmlText(text), doc_name)    

def GetErrorText():
   "Put your error text logic here.  See Python Cookbook for a useful example of error text."
   return "Some error occurred."

class Printer(HtmlEasyPrinting):
         def __init__(self):
             global frame
             HtmlEasyPrinting.__init__(self,name="Printing", parentWindow=None)

     def PreviewText(self, text, doc_name):
         HtmlEasyPrinting.PreviewText(self, text)    

     def Print(self, text, doc_name):
         self.PrintText(text, doc_name)        
This question has already been answered. Start a new discussion instead.