Python: Right click on objectlistview not showing item name selected

旧时模样 提交于 2020-01-07 01:49:29

问题


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:

  1. I am using wxpython 2.7.2.0 and tested it under Python 2.5 and Python 2.7
  2. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!