如何在wx.grid.Grid中捕获EVT_HEADER_BEGIN_RESIZE并获取动态列宽?
解决wxGrid列头拖动调整大小的事件捕获与列宽限制问题
问题根源
直接给wxGrid绑定wx.EVT_HEADER_BEGIN_RESIZE无效,因为wxGrid的列头是独立的内部控件(wxGridColHeaderWindow),事件只会发送给这个列头控件,而非Grid本身。
正确实现步骤
- 获取Grid的列头窗口对象
- 给列头窗口绑定
wx.EVT_HEADER_BEGIN_RESIZE(捕获拖动开始)和wx.EVT_HEADER_RESIZING(捕获拖动过程中的动态变化) - 在拖动过程中实时校验并限制列宽范围
修改后的完整代码
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,提问作者Сергей Кох
相关产品推荐
相关产品推荐

