Найти - Пользователи
Полная версия: [wxPython] Auto wrap и перенос строк в Grid
Начало » GUI » [wxPython] Auto wrap и перенос строк в Grid
1
Vader
Итак, нужно, чтобы текст в ячейках таблицы:
1. Переносился на новую строку, если он длиннее, чем ширина ячейки (auto wrap)
2. Воспринимал \n как перенос строки
т.е. нужно получить поведение ячеки такое же, как в обычных табличных редакторах вроде Excel.
Пытаюсь сделать приблизительно так:
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)


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


def main():

app = wx.PySimpleApp()
f = MyFrame()
f.Center()
f.Show()
app.MainLoop()


if __name__ == "__main__":
main()
Так вот, проблема в том, что в editor'e ячейчки все выглядит именно так как мне нужно, а вот в renderer'e переносы строки сделанные вручную (\n) игнорируются. Если же убрать self.SetDefaultRenderer(wx.grid.GridCellAutoWrapStringRenderer()), то \n начинает отображаться адекватно, но при этом auto wrap, естественно, не работает.
Как победить?
Vader
Решение здесь
@cckyi_boxxx
решение походу умерло с обновками (как и остальное что нашлось в сети), приделал к нему кривой костыль, выкладываю тут думаю это частая проблема, вдруг кому пригодится:

 class CutomGridCellAutoWrapStringRenderer(wx.grid.GridCellRenderer):   
    def __init__(self): 
        wx.grid.GridCellRenderer.__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)
        # начало моего костыля
        numlines = text.count('\n') + 1
        defrowsize = grid.GetDefaultRowSize()
        currowsize = grid.GetRowSize(row)
        needrowsize = currowsize // defrowsize 
        if numlines > needrowsize:
            newrowsize = numlines * defrowsize
            grid.SetRowSize(row, newrowsize)
        # конец моего костыля
        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.DrawRectangle(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()

затем остается лишь у вашего Grid вызвать SetDefaultRenderer(CutomGridCellAutoWrapStringRenderer()) и порядок, костыль кривой но рабочий.

PS: подозреваю что это должно лечиться легче, стандартными средствами wx, но я пока полностью не изучил его, из опробованного все стандартное отказало в работе wx.grid.GridCellAutoWrapStringRenderer() и wx.grid.GridCellAutoWrapStringEditor(), ну либо я криворучка))). Позже возможно выкину из этого класса лишнее, когда пойму что можно выкинуть.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB