Search code examples
pythonwxpython

Catch a click on item in ListCtrl with modifiers


I have a virtual ListCtrl with single-selection mode. Now I want to customize clicks, shift-clicks and control-clicks on listitems. To do that I need to GetModifiers() during the event handler of wx.EVT_LIST_ITEM_SELECTED. How do I do that?

I tried the following:

1) Instantiate self.keyboard = wx.KeyboardState() during init() of my custom ListCtrl. Then call self.keyboard.GetModifiers() during the event handling.

2) Instantiate the KeyboardState-class during the event handling.

To test if it works I just print all the modifiers that are captured. But it is always 0 (i.e. MOD_NONE).

I also tried to use wx.EVT_LEFT_DOWN and wx.EVT_LEFT_UP instead of wx.EVT_LIST_ITEM_SELECTED. The former has the same problems, the latter isn't even fired, when I click on a listitem.


Solution

  • This assigns both a mouse and an item selected event to the same thing, then uses event.Skip() to ensure that we see both.
    Perhaps this might give you an idea on how to progress.
    Use with Shift, Ctrl etc and combinations, mods will give you a different number depending on what is pressed.

    import wx
    
    class Myframe(wx.Frame):
        def __init__(self):
            wx.Frame.__init__(self, None)
            pan = wx.Panel(self)
            self.listC = wx.ListCtrl(pan, style=wx.LC_REPORT)
            self.listC.InsertColumn(0, 'Column1', width=50)
            self.listC.InsertColumn(1, 'Column2', width=50)
            self.listC.InsertColumn(2, 'Column3', width=50)
            self.listC.Bind(wx.EVT_LEFT_DOWN, self.ListClick)
            self.listC.Bind(wx.EVT_LIST_ITEM_SELECTED, self.ListSelected)
            self.listC.InsertStringItem(0,"Item1")
            self.listC.SetStringItem(0, 1,"Col 1 Item")
            self.listC.SetStringItem(0, 2,"Col 2 Item")
            self.listC.InsertStringItem(1,"Item2")
            self.listC.SetStringItem(1, 1,"Col 1 Item")
            self.listC.SetStringItem(1, 2,"Col 2 Item")
    
        def ListClick(self, event):
            mods = event.GetModifiers()
            print mods
            event.Skip()
    
        def ListSelected(self, event):
            print "selected"
    
    if __name__ == "__main__":
        App = wx.App()
        Myframe().Show()
        App.MainLoop()