Search code examples
pythonwxpythonwxgrid

wx.Grid and wx.StockCursor


I've created wx.Grid widget inside my frame and I want to change my type of cursor if the user is using the grid widget. I've managed to do that with wx.StockCursor and .SetCursor methods but my cursor keeps returning to standard cursor if the user moves the cursor above the intersections of cell and row borders. What is causing this?

import wx
import wx.grid as Gridw

class Frame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, 'Data selection', size=(785, 540))
        self.Centre()
#------------------------------------------------------------------------------ 
        panel = wx.Panel(self, wx.ID_ANY)
#------------------------------------------------------------------------------ 
        self.grid = Gridw.Grid(panel)
        self.grid.CreateGrid(250, 250)
        self.grid.EnableDragGridSize(0)
        self.grid.DisableDragColSize()
        self.grid.DisableDragRowSize()
        self.grid.SetColMinimalWidth(0, 100)
#------------------------------------------------------------------------------ 
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer_v = wx.BoxSizer(wx.VERTICAL)
        sizer_v.Add(wx.Button(panel, -1, 'Button'), 1, wx.CENTER | wx.ALL, 5)
        sizer.Add(self.grid, 1, wx.EXPAND, 5)
        sizer.Add(sizer_v, 0)
        panel.SetSizer(sizer)
#------------------------------------------------------------------------------ 
        self.CreateStatusBar()
        self.Show(True)
#------------------------------------------------------------------------------
        cross_c = wx.StockCursor(wx.CURSOR_CROSS)
        self.grid.SetCursor(cross_c)


if __name__ == '__main__':
    app = wx.App()
    frame = Frame().Show()
    app.MainLoop()

Solution

  • Looks like the problem is related to that you've disabled grid resizing via EnableDragGridSize(0), DisableDragColSize() and DisableDragRowSize(). This can somewhat explain why you are seeing standard cursor on the cell borders.

    Not sure if it'll help you since I don't know what OS are you using, but this works for me on linux:

    cross_c = wx.StockCursor(wx.CURSOR_CROSS)
    self.grid.GetGridWindow().SetCursor(cross_c)
    

    One more option is to listen for EVT_MOTION and set cursor in the event listener:

    self.cross_c = wx.StockCursor(wx.CURSOR_CROSS)
    self.grid.GetTargetWindow().SetCursor(self.cross_c)
    wx.EVT_MOTION(self.grid.GetGridWindow(), self.OnMouseMotion)
    
    def OnMouseMotion(self, evt):
        self.grid.GetTargetWindow().SetCursor(self.cross_c)
        evt.Skip()
    

    Hope that helps.