问题
I have been working with example stated under http://wiki.wxpython.org/PopupMenuOnRightClick .
The output expected when right clicking on an item would be Perform <action> on <item selected>
. However the output I get is Perform <action> on "."
The code I used to test the example is:
import wx
import sys
sys.path.append("..")
from ObjectListView import ObjectListView, ColumnDefn
### 2. Launcher creates wxMenu. ###
menu_titles = [ "Open",
"Properties",
"Rename",
"Delete" ]
menu_title_by_id = {}
for title in menu_titles:
menu_title_by_id[ wx.wx.NewId() ] = title
class Track(object):
"""
Simple minded object that represents a song in a music library
"""
def __init__(self, title, artist, album):
self.title = title
self.artist = artist
self.album = album
def GetTracks():
"""
Return a collection of tracks
"""
return [
Track("Sweet Lullaby", "Deep Forest", "Deep Forest"),
Track("Losing My Religion", "U2", "Out of Time"),
Track("En el Pais de la Libertad", "Leon Gieco", "Leon Gieco"),
]
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
wx.Frame.__init__(self, *args, **kwds)
self.Init()
def Init(self):
self.InitModel()
self.InitWidgets()
self.InitObjectListView()
def InitModel(self):
self.songs = GetTracks()
def InitWidgets(self):
panel = wx.Panel(self, -1)
sizer_1 = wx.BoxSizer(wx.VERTICAL)
sizer_1.Add(panel, 1, wx.ALL|wx.EXPAND)
self.SetSizer(sizer_1)
self.myOlv = ObjectListView(panel, -1, style=wx.LC_REPORT|wx.SUNKEN_BORDER)
sizer_2 = wx.BoxSizer(wx.VERTICAL)
sizer_2.Add(self.myOlv, 1, wx.ALL|wx.EXPAND, 4)
panel.SetSizer(sizer_2)
self.Layout()
def InitObjectListView(self):
self.myOlv.SetColumns([
ColumnDefn("Title", "left", 120, "title"),
ColumnDefn("Artist", "left", 100, "artist"),
ColumnDefn("Album", "left", 100, "album")
])
self.myOlv.SetObjects(self.songs)
self.myOlv.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.RightClick)
def RightClick(self,event):
# record what was clicked
self.list_item_clicked = right_click_context = event.GetString()
menu = wx.wx.Menu()
menu.Bind(wx.EVT_MENU, self.MenuSelectionCb)
for (id,title) in menu_title_by_id.items():
### 3. Launcher packs menu with Append. ###
menu.Append( id, title )
### 5. Launcher displays menu with call to PopupMenu, invoked on the source component, passing event's GetPoint. ###
#self.frame.PopupMenu( menu, event.GetPoint() )
frame_1.PopupMenu(menu, event.GetPoint() )
menu.Destroy() # destroy to avoid mem leak
def MenuSelectionCb( self, event ):
# do something
operation = menu_title_by_id[ event.GetId() ]
target = self.list_item_clicked
print 'Perform "%(operation)s" on "%(target)s."' % vars()
class MyPopupMenu(wx.Menu):
def __init__(self, parent):
super(MyPopupMenu, self).__init__()
self.parent = parent
mmi = wx.MenuItem(self, wx.NewId(), 'Minimize')
self.AppendItem(mmi)
self.Bind(wx.EVT_MENU, self.OnMinimize, mmi)
cmi = wx.MenuItem(self, wx.NewId(), 'Close')
self.AppendItem(cmi)
self.Bind(wx.EVT_MENU, self.OnClose, cmi)
def OnMinimize(self, e):
self.parent.Iconize()
def OnClose(self, e):
self.parent.Close()
if __name__ == '__main__':
app = wx.PySimpleApp(1)
wx.InitAllImageHandlers()
frame_1 = MyFrame(None, -1, "ObjectListView Track Test")
app.SetTopWindow(frame_1)
frame_1.Show()
app.MainLoop()
So, how to ensure to get the corresponding item name when right clicking and selecting an action for that item?
Notes:
- I am using wxpython 2.7.2.0 and tested it under Python 2.5 and Python 2.7
- This has been asked already under python: Right Click on list menu not showing item selected . However the solution provided (to change GetText to GetString) hadn't the expected results.
回答1:
To get the selected object inside of the RightClick event handler you can use objectlistviews GetSelectedObject() method, the code below is modified to use this method and then display the selected objects title.
I don't think you will get the selected object from the event wx.EVT_LIST_ITEM_RIGHT_CLICK as it is not a objectlistview specific event, its a plain listview event.
import wx
import sys
sys.path.append("..")
from ObjectListView import ObjectListView, ColumnDefn
### 2. Launcher creates wxMenu. ###
menu_titles = [ "Open",
"Properties",
"Rename",
"Delete" ]
menu_title_by_id = {}
for title in menu_titles:
menu_title_by_id[ wx.NewId() ] = title
class Track(object):
"""
Simple minded object that represents a song in a music library
"""
def __init__(self, title, artist, album):
self.title = title
self.artist = artist
self.album = album
def GetTracks():
"""
Return a collection of tracks
"""
return [
Track("Sweet Lullaby", "Deep Forest", "Deep Forest"),
Track("Losing My Religion", "U2", "Out of Time"),
Track("En el Pais de la Libertad", "Leon Gieco", "Leon Gieco"),
]
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
wx.Frame.__init__(self, *args, **kwds)
self.Init()
def Init(self):
self.InitModel()
self.InitWidgets()
self.InitObjectListView()
def InitModel(self):
self.songs = GetTracks()
def InitWidgets(self):
panel = wx.Panel(self, -1)
sizer_1 = wx.BoxSizer(wx.VERTICAL)
sizer_1.Add(panel, 1, wx.ALL | wx.EXPAND)
self.SetSizer(sizer_1)
self.myOlv = ObjectListView(panel, -1, style=wx.LC_REPORT | wx.SUNKEN_BORDER)
sizer_2 = wx.BoxSizer(wx.VERTICAL)
sizer_2.Add(self.myOlv, 1, wx.ALL | wx.EXPAND, 4)
panel.SetSizer(sizer_2)
self.Layout()
def InitObjectListView(self):
self.myOlv.SetColumns([
ColumnDefn("Title", "left", 120, "title"),
ColumnDefn("Artist", "left", 100, "artist"),
ColumnDefn("Album", "left", 100, "album")
])
self.myOlv.SetObjects(self.songs)
self.myOlv.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.RightClick)
def RightClick(self, event):
# record what was clicked
self.list_item_clicked = self.myOlv.GetSelectedObject()
menu = wx.Menu()
menu.Bind(wx.EVT_MENU, self.MenuSelectionCb)
for (id_, title) in menu_title_by_id.items():
### 3. Launcher packs menu with Append. ###
menu.Append(id_, title)
### 5. Launcher displays menu with call to PopupMenu, invoked on the source component, passing event's GetPoint. ###
# self.frame.PopupMenu( menu, event.GetPoint() )
frame_1.PopupMenu(menu, event.GetPoint())
menu.Destroy() # destroy to avoid mem leak
def MenuSelectionCb(self, event):
# do something
operation = menu_title_by_id[ event.GetId() ]
target = self.list_item_clicked.title
print 'Perform "%(operation)s" on "%(target)s."' % vars()
class MyPopupMenu(wx.Menu):
def __init__(self, parent):
super(MyPopupMenu, self).__init__()
self.parent = parent
mmi = wx.MenuItem(self, wx.NewId(), 'Minimize')
self.AppendItem(mmi)
self.Bind(wx.EVT_MENU, self.OnMinimize, mmi)
cmi = wx.MenuItem(self, wx.NewId(), 'Close')
self.AppendItem(cmi)
self.Bind(wx.EVT_MENU, self.OnClose, cmi)
def OnMinimize(self, e):
self.parent.Iconize()
def OnClose(self, e):
self.parent.Close()
if __name__ == '__main__':
app = wx.App(True)
wx.InitAllImageHandlers()
frame_1 = MyFrame(None, -1, "ObjectListView Track Test")
app.SetTopWindow(frame_1)
frame_1.Show()
app.MainLoop()
来源:https://stackoverflow.com/questions/36581286/python-right-click-on-objectlistview-not-showing-item-name-selected