This week, I needed to figure out how to attach an event handler that would fire when I double-clicked an item (i.e. row) in an ObjectListView widget that was in LC_REPORT mode. For some reason, there isn’t an obvious mouse event for that. There is an EVT_LIST_ITEM_RIGHT_CLICK and an EVT_LIST_ITEM_MIDDLE_CLICK, but nothing for LEFT clicks of any sort. After a bit of searching on Google, I found that I can get it to work by using EVT_LIST_ITEM_ACTIVATED. This will fire when an item is double-clicked and when an item is selected and the user presses ENTER. Here’s a code example:
import wx from ObjectListView import ObjectListView, ColumnDefn ######################################################################## class Results(object): """""" #---------------------------------------------------------------------- def __init__(self, tin, zip_code, plus4, name, address): """Constructor""" self.tin = tin self.zip_code = zip_code self.plus4 = plus4 self.name = name self.address = address ######################################################################## class DCPanel(wx.Panel): """""" #---------------------------------------------------------------------- def __init__(self, parent): """Constructor""" wx.Panel.__init__(self, parent=parent) mainSizer = wx.BoxSizer(wx.VERTICAL) self.test_data = [Results("123456789", "50158", "0065", "Patti Jones", "111 Centennial Drive"), Results("978561236", "90056", "7890", "Brian Wilson", "555 Torque Maui"), Results("456897852", "70014", "6545", "Mike Love", "304 Cali Bvld") ] self.resultsOlv = ObjectListView(self, style=wx.LC_REPORT|wx.SUNKEN_BORDER) self.resultsOlv.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.onDoubleClick) self.setResults() mainSizer.Add(self.resultsOlv, 1, wx.EXPAND|wx.ALL, 5) self.SetSizer(mainSizer) #---------------------------------------------------------------------- def onDoubleClick(self, event): """ When the item is double-clicked or "activated", do something """ print "in onDoubleClick method" #---------------------------------------------------------------------- def setResults(self): """""" self.resultsOlv.SetColumns([ ColumnDefn("TIN", "left", 100, "tin"), ColumnDefn("Zip", "left", 75, "zip_code"), ColumnDefn("+4", "left", 50, "plus4"), ColumnDefn("Name", "left", 150, "name"), ColumnDefn("Address", "left", 200, "address") ]) self.resultsOlv.CreateCheckStateColumn() self.resultsOlv.SetObjects(self.test_data) ######################################################################## class DCFrame(wx.Frame): """""" #---------------------------------------------------------------------- def __init__(self): """Constructor""" wx.Frame.__init__(self, parent=None, title="Double-click Tutorial") panel = DCPanel(self) #---------------------------------------------------------------------- if __name__ == "__main__": app = wx.App(False) frame = DCFrame() frame.Show() app.MainLoop()
Pretty straight-forward, right? I hope it’ll help you if you ever need to know how to do this. This method should work with a ListCtrl as well.
No problem. I’m glad someone reads them. I don’t think the wxPython stuff pulls in very many readers.
I’ve been thinking about writing a book (or books) for a while now, including something that’s intermediate. This sounds like an interesting idea. I’ll think about it.
Oh, now I find this! I spent the better part of my hobby hours yesterday figuring this out. ~DevPlayer
There’s a problem if the list contains a check-state column: each time when you press space key simply to check that row, this action would be considered as double click at the same time. Is there other way to track double click event?
You would probably have to catch the Key event and veto it.
Thanks for your quick reply! Well, for me `wx.EVT_LEFT_DCLICK` is good enough to do the work, just need to check if the double-click actually hits a row or not.