【问题标题】:Error printing a second time in Wxpython in python在 python 中的 Wxpython 中第二次打印时出错
【发布时间】:2020-06-23 16:12:45
【问题描述】:

我有一个问题,但这次它与 Wxpython 的关系比与 Tkinter 的关系更多。我通常不使用这个模块,所以我对它知之甚少。 在以下代码中,在 Tkinter 测试窗口中按 Enter 键将打开 windows 打印窗口。如果发送打印到 PDF,它可以完美运行。 但是如果重复这个过程,就会出现错误。下面是测试代码和错误。

代码

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))

错误

  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'

有人知道问题的解决方法吗?谢谢。

【问题讨论】:

  • 我一直在测试,似乎如果直接调用绑定上的f_imprimir,则不会发生错误。但这不允许我执行异步功能。

标签: python printing wxpython python-multithreading dc


【解决方案1】:

我进行了测试,这段代码应该可以解决我遇到的所有问题,包括这个问题。我想这是可行的,因为它让 Tkinter 有时间在打印机选择窗口启动之前更新窗口。

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()))

【讨论】:

    猜你喜欢
    • 2015-01-28
    • 2013-01-11
    • 1970-01-01
    • 2018-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    相关资源
    最近更新 更多