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

如何在wx.grid.Grid中捕获EVT_HEADER_BEGIN_RESIZE并获取动态列宽?

解决wxGrid列头拖动调整大小的事件捕获与列宽限制问题

问题根源

直接给wxGrid绑定wx.EVT_HEADER_BEGIN_RESIZE无效,因为wxGrid的列头是独立的内部控件(wxGridColHeaderWindow),事件只会发送给这个列头控件,而非Grid本身。

正确实现步骤

  1. 获取Grid的列头窗口对象
  2. 给列头窗口绑定wx.EVT_HEADER_BEGIN_RESIZE(捕获拖动开始)和wx.EVT_HEADER_RESIZING(捕获拖动过程中的动态变化)
  3. 在拖动过程中实时校验并限制列宽范围

修改后的完整代码

import wx
import wx.grid


class MyGrid(wx.grid.Grid):
    def __init__(self, parent):
        wx.grid.Grid.__init__(self, parent)
        self.CreateGrid(12, 8)
        self.parent = parent
        
        # 获取列头窗口并绑定事件
        col_header = self.GetColHeaderWindow()
        col_header.Bind(wx.EVT_HEADER_BEGIN_RESIZE, self.OnHeaderBeginResize)
        col_header.Bind(wx.EVT_HEADER_RESIZING, self.OnHeaderResizing)
        
        # 可选:绑定列宽调整结束事件
        self.Bind(wx.grid.EVT_GRID_CMD_COL_SIZE, self.OnColSizeEnd)
        
        # 设置列宽限制范围(示例值)
        self.min_col_width = 100
        self.max_col_width = 300
        self.current_resizing_col = -1
        self.initial_col_width = 0

    def OnHeaderBeginResize(self, event):
        # 记录开始拖动的列索引和初始宽度
        self.current_resizing_col = event.GetColumn()
        self.initial_col_width = self.GetColSize(self.current_resizing_col)
        print(f"开始调整列 {self.current_resizing_col},初始宽度:{self.initial_col_width}")
        event.Skip()

    def OnHeaderResizing(self, event):
        # 实时限制列宽
        if self.current_resizing_col == -1:
            event.Skip()
            return
        
        new_width = event.GetNewWidth()
        # 校验宽度是否在限制范围内
        if new_width < self.min_col_width:
            new_width = self.min_col_width
        elif new_width > self.max_col_width:
            new_width = self.max_col_width
        
        # 更新事件的新宽度,生效限制
        event.SetNewWidth(new_width)
        print(f"列 {self.current_resizing_col} 动态调整宽度:{new_width}")
        event.Skip()

    def OnColSizeEnd(self, event):
        # 列宽调整结束后的处理
        col = event.GetCol()
        final_width = self.GetColSize(col)
        print(f"列 {col} 调整完成,最终宽度:{final_width}")
        self.current_resizing_col = -1
        event.Skip()


class MyForm(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent=None, title="Test Grid", size=(1000, 500))
        panel = wx.Panel(self)
        myGrid = MyGrid(panel)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(myGrid, -1, wx.EXPAND)
        panel.SetSizer(sizer)


if __name__ == "__main__":
    app = wx.App()
    frame = MyForm().Show()
    app.MainLoop()

代码说明

  • GetColHeaderWindow():获取Grid的列头控件,所有列头相关的事件都需要绑定到这个对象上
  • EVT_HEADER_BEGIN_RESIZE:记录拖动起始状态,便于后续逻辑处理
  • EVT_HEADER_RESIZING:拖动过程中实时修改宽度值,强制限制在设定的最小/最大范围内
  • EVT_GRID_CMD_COL_SIZE:可选绑定,用于处理调整结束后的最终状态

内容的提问来源于stack exchange,提问作者Сергей Кох

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 01:37:11