自动换行和wxPython网格中的换行符 [英] Auto wrap and newlines in wxPython grid

查看:1153
本文介绍了自动换行和wxPython网格中的换行符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


  1. 不适合单元格


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


即,如表格编辑器中的行为,如MS Excel,OO Calc等等,当你为单元格启用'wrap words'选项时。



我正在尝试这样做如下所示:

  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\\\
Line2\\\
Line3)
self.SetRowSize(0,100)


class MyFrame(wx.Frame):

def __init __(self,parent = None,title = Multiline):

wx.Frame .__ init __(self,parent,-1,title)

self.Bind(w x.EVT_CHAR_HOOK,self.on_frame_char_hook)

panel = wx.Panel(self)

vbox = wx.BoxSizer(wx.VERTICAL)
panel.SetSizer vbox)

grid = MyGrid(面板)
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)

#在单元编辑器中作为换行符执行CTRL + ENTER
def on_frame_char_hook(self,event):

if event.CmdDown()和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()),那么换行符在编辑器和渲染器中都会正确处理,但显然自动换行并不会工作。



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

解决方案

通过编写自定义渲染器解决了这个问题:

  from wx.lib import wordwrap 
import wx.grid


class CutomGridCellAutoWrapStringRenderer(wx.grid.PyGridCellRenderer):
def __init __(self):
wx.grid.PyGridCellRenderer .__ init __(self)

$ drawButton(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 = GRI d.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)
$ b $ 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)
$ b $ def Clone(self):
return CutomGridCellAutoWrapStringRenderer()


I want to implement a grid with the cells that have the following behaviour:

  1. cell text should be wrapped if it doesn't fit to the cell

  2. newlines (\n) in the cell text should be processed as well

i.e. the same behaviour as in table editors like MS Excel, OO Calc, etc. when you enable the 'wrap words' option for cells.

I'm trying to do this as follows:

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

But this code doesn't work as expected - newlines processed correctly in the cell editor, but ignored in the cell renderer. If I remove the self.SetDefaultRenderer(wx.grid.GridCellAutoWrapStringRenderer()) then newlines processed correcly both in the editor and renderer, but obviously auto wrapping in the renderer doesn't work.

Does anybody know how to solve this?

解决方案

Solved this problem by writing a custom renderer:

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

这篇关于自动换行和wxPython网格中的换行符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆