I have a problem, but this time it has more relationship with Wxpython than with Tkinter. I don't usually use this module, so I know very little about it. In the following code, pressing the Enter key in the Tkinter test window will open the windows printing window. If sent to print to PDF, it works perfect. But if the process is repeated, an error will occur. Below are the test code and the error.
CODE
from threading import Thread
from tkinter import Tk
import wx
def f_imprimir(codigo):
class TextDocPrintout(wx.Printout):
def __init__(self):
wx.Printout.__init__(self)
def OnPrintPage(self, page):
dc = self.GetDC()
ppiPrinterX, ppiPrinterY = self.GetPPIPrinter()
ppiScreenX, ppiScreenY = self.GetPPIScreen()
logScale = float(ppiPrinterX)/float(ppiScreenX)
pw, ph = self.GetPageSizePixels()
dw, dh = dc.GetSize()
scale = logScale * float(dw)/float(pw)
dc.SetUserScale(scale, scale)
logUnitsMM = float(ppiPrinterX)/(logScale*25.4)
codigo(dc, logUnitsMM)
return True
class PrintFrameworkSample(wx.Frame):
def OnPrint(self):
pdata = wx.PrintData()
pdata.SetPaperId(wx.PAPER_A4)
pdata.SetOrientation(wx.LANDSCAPE)
data = wx.PrintDialogData(pdata)
printer = wx.Printer(data)
printout = TextDocPrintout()
useSetupDialog = True
if not printer.Print(self, printout, useSetupDialog) and printer.GetLastError() == wx.PRINTER_ERROR:
wx.MessageBox(
"There was a problem printing.\n"
"Perhaps your current printer is not set correctly?",
"Printing Error", wx.OK)
else:
data = printer.GetPrintDialogData()
printout.Destroy()
self.Destroy()
app=wx.App(False)
PrintFrameworkSample().OnPrint()
def funcion(dc, MM):
dc.DrawText("hola mundo", MM*16, MM*73)
def imprimir(codigo):
t = Thread(target=f_imprimir, args=(codigo,))
t.start()
Tk().bind("<Return>", lambda Event:imprimir(funcion))
ERROR
File "C:\Users\DANTE\Google Drive\JNAAB\DESARROLLO\pruebas\t\s\prueba.py", line 11, in OnPrintPage
dc = self.GetDC()
AttributeError: 'TextDocPrintout' object has no attribute 'GetDC'
Does anyone know the solution to the problem? Thank you.
I did the tests and this code should be a solution for all the problems I have, including this one. I suppose this works because it gives Tkinter time to update the window before the Printer Selection Window starts.
from tkinter import Tk, Entry
import wx
def f_imprimir(v,codigo):
class TextDocPrintout(wx.Printout):
"""
A printout class that is able to print simple text documents.
Does not handle page numbers or titles, and it assumes that no
lines are longer than what will fit within the page width. Those
features are left as an exercise for the reader. ;-)
"""
def __init__(self):#, text, title, margins):
wx.Printout.__init__(self)#, title)
self.numPages = 1
def HasPage(self, page):
return page <= self.numPages
def GetPageInfo(self):
return (1, self.numPages, 1, self.numPages)
def CalculateScale(self, dc):
# Scale the DC such that the printout is roughly the same as
# the screen scaling.
ppiPrinterX, ppiPrinterY = self.GetPPIPrinter()
ppiScreenX, ppiScreenY = self.GetPPIScreen()
logScale = float(ppiPrinterX)/float(ppiScreenX)
# Now adjust if the real page size is reduced (such as when
# drawing on a scaled wx.MemoryDC in the Print Preview.) If
# page width == DC width then nothing changes, otherwise we
# scale down for the DC.
pw, ph = self.GetPageSizePixels()
dw, dh = dc.GetSize()
scale = logScale * float(dw)/float(pw)
# Set the DC's scale.
dc.SetUserScale(scale, scale)
# Find the logical units per millimeter (for calculating the
# margins)
self.logUnitsMM = float(ppiPrinterX)/(logScale*25.4)
def OnPreparePrinting(self):
# calculate the number of pages
dc = self.GetDC()
self.CalculateScale(dc)
def OnPrintPage(self, page):
codigo(self.GetDC(), self.logUnitsMM)
return True
class PrintFrameworkSample(wx.Frame):
def __init__(self):
wx.Frame.__init__(self)
# initialize the print data and set some default values
self.pdata = wx.PrintData()
self.pdata.SetPaperId(wx.PAPER_A4)
self.pdata.SetOrientation(wx.PORTRAIT)
def OnPrint(self):#, evt):
data = wx.PrintDialogData(self.pdata)
printer = wx.Printer(data)
printout = TextDocPrintout()
useSetupDialog = True
if not printer.Print(self, printout, useSetupDialog) and printer.GetLastError() == wx.PRINTER_ERROR:
wx.MessageBox(
"Hubo un problema al imprimir.\n"
"Su impresora está configurada correctamente?",
"Error al Imprimir", wx.OK)
else:
data = printer.GetPrintDialogData()
self.pdata = wx.PrintData(data.GetPrintData()) # force a copy
printout.Destroy()
app=wx.App(False)
PrintFrameworkSample().OnPrint()
app.MainLoop()
entrada["state"] = "normal"
def funcion(dc, MM):
dc.DrawText("hola mundo", MM*16, MM*73)
v=Tk()
entrada=Entry(v)
entrada.pack()
after = lambda:v.after(10,lambda:f_imprimir(v,funcion))
v.bind("<Return>", lambda Event:(entrada.config(state="disable"),after()))