You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 15:12:55