如何让wx.grid.Grid的活动单元格在控件失焦时仍保持高亮?
实现wxGrid无焦点时保持活动单元格高亮
要让wxGrid在未获得焦点时也显示活动单元格的灰色高亮边框,有两种简洁的实现方式,都是基于自定义Grid子类或渲染器绕过默认的焦点判断逻辑:
方法一:重载Grid的DrawCellHighlight方法
默认情况下,wxGrid的DrawCellHighlight方法只会在Grid拥有焦点时绘制高亮边框。我们可以直接重载这个方法,强制绘制高亮,忽略焦点状态:
import wx import wx.grid class PersistentHighlightGrid(wx.grid.Grid): def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.WANTS_CHARS, name="grid"): super().__init__(parent, id, pos, size, style, name) def DrawCellHighlight(self, dc, rect, attr): # 绘制和默认样式一致的灰色高亮边框 dc.SetPen(wx.Pen(wx.Colour(192, 192, 192), 1)) dc.SetBrush(wx.TRANSPARENT_BRUSH) dc.DrawRectangle(rect)
使用这个自定义Grid类替代原生wx.grid.Grid即可,无需额外配置。
方法二:自定义单元格渲染器
如果需要更灵活的控制(比如单独指定某些列/行的高亮逻辑),可以自定义单元格渲染器,在绘制时主动检查当前单元格是否为光标所在位置,强制添加高亮边框:
import wx import wx.grid class HighlightRenderer(wx.grid.GridCellRenderer): def Draw(self, grid, attr, dc, rect, row, col, isSelected): # 先执行默认绘制逻辑,保证单元格内容和基础样式正常显示 super().Draw(grid, attr, dc, rect, row, col, isSelected) # 检查当前单元格是否是光标定位的单元格 cursor_row, cursor_col = grid.GetGridCursorCoords() if row == cursor_row and col == cursor_col: # 绘制灰色高亮边框 dc.SetPen(wx.Pen(wx.Colour(192, 192, 192), 1)) dc.SetBrush(wx.TRANSPARENT_BRUSH) dc.DrawRectangle(rect) # 使用示例 class MyFrame(wx.Frame): def __init__(self): super().__init__(None, title="Grid Persistent Highlight", size=(600, 400)) panel = wx.Panel(self) self.grid = wx.grid.Grid(panel) self.grid.CreateGrid(8, 6) # 给Grid设置自定义渲染器 self.grid.SetDefaultRenderer(HighlightRenderer()) # 添加测试按钮,用于让Grid失去焦点 test_btn = wx.Button(panel, label="点击切换焦点") test_btn.Bind(wx.EVT_BUTTON, lambda e: test_btn.SetFocus()) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.grid, 1, wx.EXPAND | wx.ALL, 10) sizer.Add(test_btn, 0, wx.ALIGN_CENTER | wx.BOTTOM, 10) panel.SetSizer(sizer) self.Show() if __name__ == "__main__": app = wx.App() frame = MyFrame() app.MainLoop()
注意事项
- 两种方法的高亮样式都和wxGrid默认的灰色边框保持一致,你可以通过修改
wx.Pen的颜色参数来调整高亮颜色。 - 选中单元格的蓝色背景样式不受影响,和高亮边框可以共存,不会产生冲突。
内容的提问来源于stack exchange,提问作者z80crew
相关产品推荐
相关产品推荐

