使用等宽字体 Wxpython 制作 table

Make table with monospaced font Wxpython

我正在尝试用 Wxpython 中的字符创建 table。类型:

┌─────────┬──────────┐
│columna1 │ columna2 │
├─────────┼──────────┤
│dato1    │ dato2    │
├─────────┼──────────┤
│dato3    │ dato4    │
└─────────┴──────────┘

我使用代码dc.SetFont(wx.Font(12, wx.TELETYPE, wx.NORMAL, wx.NORMAL))

但是等宽似乎不适用于 table 中的行,因此会导致类似这样的结果:

┌─────────┬──────────┐
│columna1  │ columna2 │
├─────────┼──────────┤
│dato1      │ dato2    │
├─────────┼──────────┤
│dato3   │ dato4    │
└─────────┴──────────┘

我打算将字体应用于要发送到打印机的文本。谢谢。

这是一个有错误的示例代码:

import wx

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)

    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.numPages = 1
        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):
        dc = self.GetDC()
        dc.SetFont(wx.Font(12, wx.TELETYPE, wx.NORMAL, wx.NORMAL))

        texto  = "┌─────────┬──────────┐\n"
        texto += "│columna1 │ columna2 │\n"
        texto += "├─────────┼──────────┤\n"
        texto += "│dato1    │ dato2    │\n"
        texto += "├─────────┼──────────┤\n"
        texto += "│dato3    │ dato4    │\n"
        texto += "└─────────┴──────────┘"

        dc.DrawText(texto, self.logUnitsMM*15, self.logUnitsMM*15)

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

指定字体面名可以强制解决问题:
dc.SetFont(wx.Font(12, wx.FONTFAMILY_TELETYPE, wx.NORMAL, wx.NORMAL, faceName="Monospace"))
然而,有一个 FontEnumerator 可用,可用于 select 从可用的字体中选择合适的字体。
下面是它的使用示例,寻找固定宽度的字体。

import wx

class MyPanel(wx.Panel):

    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1)

        fonts = wx.FontEnumerator()
        fonts.EnumerateFacenames(wx.FONTENCODING_SYSTEM,fixedWidthOnly=True)
        font_list = fonts.GetFacenames(wx.FONTENCODING_SYSTEM,fixedWidthOnly=True)

        list_text = wx.StaticText(self, -1, "Face names:")
        self.font = wx.ListBox(self, -1, size=(200, 500), choices=font_list)
        self.font_size = wx.SpinCtrl(self, wx.ID_ANY, min=6, max=50, initial=16)
        self.sample = wx.StaticText(self, -1, "Sample ")

        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(list_text, 0, wx.ALL, 5)
        sizer.Add(self.font, 0, wx.ALL, 5)
        sizer.Add(self.font_size, 0, wx.ALL, 5)
        sizer.Add(self.sample, 0, wx.ALL, 5)

        self.SetSizer(sizer)
        self.Layout()

        self.font.Bind(wx.EVT_LISTBOX, self.OnSelect)
        self.font_size.Bind(wx.EVT_SPINCTRL, self.OnSelect)
        self.font.SetSelection(0)
        self.font_size.SetToolTip('Select font size')
        self.OnSelect(None)

    def OnSelect(self, evt):
        facename = self.font.GetStringSelection()
        size = self.font_size.GetValue()
        font = wx.Font(size, family=wx.DEFAULT, style=wx.NORMAL, weight=wx.NORMAL, underline=False, faceName=facename)
        self.sample.SetLabel(facename)
        self.sample.SetFont(font)
        self.Refresh()

class MyForm(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None,title="Fixed Width FontEnumerator", size=(800,600))
        panel = MyPanel(self)


if __name__ == "__main__":
    app = wx.App(False)
    frame = MyForm()
    frame.Show()
    app.MainLoop()

您尝试过使用 三重引号 吗?请试试这个并告诉我:

texto  = '''
┌─────────┬──────────┐
│columna1 │ columna2 │
├─────────┼──────────┤
│dato1    │ dato2    │
├─────────┼──────────┤
│dato3    │ dato4    │
└─────────┴──────────┘
'''
print(texto)

祝你好运!