Автоматическая переноска и переносы в сетке wxPython - PullRequest
3 голосов
/ 03 мая 2011

Я хочу реализовать сетку с ячейками, которые имеют следующее поведение:

  1. текст ячейки должен быть перенесен, если он не помещается в ячейку

  2. переводы строки (\ n) в тексте ячейки также должны обрабатываться

, то есть то же поведение, что и в редакторах таблиц, таких как 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 Ответ

3 голосов
/ 04 мая 2011

Решил эту проблему, написав собственный рендер:

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