wxPython网格中的自动换行和换行

时间:2011-05-03 10:43:44

标签: python grid wxpython newline wrapping

我想用具有以下行为的单元格实现网格:

  1. 如果单元格文本不适合单元格,则应将其包装

  2. 单元格文本中的换行符(\ n)也应该被处理

  3. 即。当您为单元格启用“换行词”选项时,与MS Excel,OO Calc等表格编辑器中的行为相同。

    我正在尝试按如下方式执行此操作:

    import wx 
    import wx.grid 
    
    class MyGrid(wx.grid.Grid): 
    
        def __init__(self, parent = None, style = wx.WANTS_CHARS): 
    
            wx.grid.Grid.__init__(self, parent, -1, style = style) 
    
            self.CreateGrid(10, 10) 
    
            self.editor = wx.grid.GridCellAutoWrapStringEditor() 
            self.SetDefaultEditor(self.editor)
    
            self.SetDefaultRenderer(wx.grid.GridCellAutoWrapStringRenderer()) 
    
            self.SetCellValue(0, 0, "Line1\nLine2\nLine3") 
            self.SetRowSize(0, 100) 
    
    
    class MyFrame(wx.Frame): 
    
        def __init__(self, parent = None, title = "Multiline"): 
    
            wx.Frame.__init__(self, parent, -1, title) 
    
            self.Bind(wx.EVT_CHAR_HOOK, self.on_frame_char_hook) 
    
            panel = wx.Panel(self) 
    
            vbox = wx.BoxSizer(wx.VERTICAL) 
            panel.SetSizer(vbox) 
    
            grid = MyGrid(panel) 
            vbox.Add(grid, 1, wx.EXPAND | wx.ALL, 5) 
            self.grid = grid 
    
            btn_exit = wx.Button(panel, -1, "Exit") 
            vbox.Add(btn_exit, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 10) 
    
        #Proceed CTRL+ENTER as newline in the cell editor
        def on_frame_char_hook(self, event): 
    
            if event.CmdDown() and event.GetKeyCode() == wx.WXK_RETURN: 
                if self.grid.editor.IsCreated(): 
                    self.grid.editor.StartingKey(event) 
                else: 
                    event.Skip 
            else: 
                event.Skip()
    
    
    if __name__ == "__main__": 
        app = wx.PySimpleApp() 
        f = MyFrame() 
        f.Center() 
        f.Show() 
        app.MainLoop()
    

    但是这段代码没有按预期工作 - 在单元格编辑器中正确处理换行符,但在单元格渲染器中忽略了换行符。如果我删除了self.SetDefaultRenderer(wx.grid.GridCellAutoWrapStringRenderer()),那么在编辑器和渲染器中都会正确处理新行,但显然在渲染器中自动换行不起作用。

    有人知道如何解决这个问题吗?

1 个答案:

答案 0 :(得分:3)

通过编写自定义渲染器来解决此问题:

from wx.lib import wordwrap
import wx.grid


class CutomGridCellAutoWrapStringRenderer(wx.grid.PyGridCellRenderer):   
    def __init__(self): 
        wx.grid.PyGridCellRenderer.__init__(self)

    def Draw(self, grid, attr, dc, rect, row, col, isSelected):
        text = grid.GetCellValue(row, col)
        dc.SetFont( attr.GetFont() ) 
        text = wordwrap.wordwrap(text, grid.GetColSize(col), dc, breakLongWords = False)
        hAlign, vAlign = attr.GetAlignment()       
        if isSelected: 
            bg = grid.GetSelectionBackground() 
            fg = grid.GetSelectionForeground() 
        else: 
            bg = attr.GetBackgroundColour()
            fg = attr.GetTextColour() 
        dc.SetTextBackground(bg) 
        dc.SetTextForeground(fg)
        dc.SetBrush(wx.Brush(bg, wx.SOLID))
        dc.SetPen(wx.TRANSPARENT_PEN)
        dc.DrawRectangleRect(rect)            
        grid.DrawTextRectangle(dc, text, rect, hAlign, vAlign)

    def GetBestSize(self, grid, attr, dc, row, col): 
        text = grid.GetCellValue(row, col)
        dc.SetFont(attr.GetFont())
        text = wordwrap.wordwrap(text, grid.GetColSize(col), dc, breakLongWords = False)
        w, h, lineHeight = dc.GetMultiLineTextExtent(text)                   
        return wx.Size(w, h)        

    def Clone(self): 
        return CutomGridCellAutoWrapStringRenderer()