Search code examples
pythonwxpythonwxwidgets

wx.ListCtrl: how can I select a row on EVT_RIGHT_DOWN?


I'm writing a simple database GUI with wxpython.

In order to display my database entries, I'm using a wx.ListCtrl. Let's consider the following code snippet:

class BookList(wx.ListCtrl):
  def __init__(self, parent, ID=wx.ID_ANY):
    wx.ListCtrl.__init__(self, parent, ID)

    self.InsertColumn(0, 'Title')
    self.InsertColumn(1, 'Author')

    # set column width ...

    self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)


  def OnRightDown(self, event):
    menu = wx.Menu()
    delete = menu.Append(wx.ID_ANY, 'Delete Item')

    self.Bind(wx.EVT_MENU, self.OnDelete, delete)

    # select row

    self.PopupMenu(menu, event.GetPosition())

I can't figure out how to select the row before spawning the menu.

I thought about two possible solutions:

  1. Use wx.ListCtrl.Select(), but I don't know how to obtain idx parameter corresponding to the row I want to select.
  2. Trigger wx.EVT_LEFT_DOWN, but I don't know how (and even if) it could be done.

Am I on the right way? Is there any better solution?

Thanks in advance.


Solution

  • I found a solution that involves both the possible solutions I guessed.

    I have keep track of the currently selected row. The snippet speaks itself:

    class BookList(wx.ListCtrl):
      def __init__(self, parent, ID=wx.ID_ANY):
        wx.ListCtrl.__init__(self, parent, ID)
    
        self.InsertColumn(0, 'Title')
        self.InsertColumn(1, 'Author')
    
        # set column width ...
    
        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
    
        # currently selected row
        self.cur = None
    
    
      def OnLeftDown(self, event):
        if self.cur != None:
          self.Select( self.cur, 0) # deselect currently selected item
    
        x,y = event.GetPosition()
        row,flags = self.HitTest( (x,y) )
    
        self.Select(row)
        self.cur = row
    
    
      def OnRightDown(self, event):
        menu = wx.Menu()
        delete = menu.Append(wx.ID_ANY, 'Delete Item')
    
        self.Bind(wx.EVT_MENU, self.OnDelete, delete)
    
        # select row
        self.OnLeftDown(event)
    
        self.PopupMenu(menu, event.GetPosition())