2017-06-23 49 views
1

我有一个wxpython listctrl,其中包含4列[A,B,C,D]。用户从listctrl中选择任意一行。现在我在我的gui中有一个按钮,所以当我单击时,我想从所选行打印D列的值。 例如允许用户选择该行:
[PYTHON,JAVA,MATLAB,RUBY]
现在,如果用户点击该按钮,它应该给输出:RUBY
我这样如何绑定wxpython listctrl onclick按钮事件

self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnPlot, self.list) 

self.list.Append((j[0],j[1],j[2],j[3]))  #values are inserted in the listctrl 
绑定按钮

和OnPlot事件我定义为: def OnPlot(self, event): click = event.GetText()

它不起作用。我怎样才能做到这一点?

回答

2

本次活动将通过选定项的指数从listctrl的。
使用索引获取listctrl中的项目和列,在这种情况下为3.
获取列的文本。
即:

def on_plot(self, event): 
    ind = event.GetIndex() 
    item = self.list_ctrl.GetItem(ind,3) 
    print item.GetText() 

这假定您已经绑定的listctrl的是这样的:

self.list_ctrl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.on_plot, self.list_ctrl) 

编辑:
关于你的评论和编辑的问题的称号。 你不能绑定任意事件。一个按钮有一组定义的事件,就像一个listctrl一样,并且两个都不会遇到。解决您的问题的方法是将按钮绑定到按钮事件。

plot_button.Bind(wx.EVT_BUTTON, self.on_plot) 

然后定义on_plot这样的:

def on_plot(self, event): 
    ind = self.list_ctrl.GetFirstSelected() 
    if ind >=0: 
     item = self.list_ctrl.GetItem(ind,3) 
     print item.GetText() 

正如你会看到它达到相同的最终结果,但是,这是一个很大的,但是,你已经不得不点击listctrl的选择项目。既然如此,您可能已经使用第一种方法取得了相同的结果,而无需首先定义按钮,并且使用此方法,您必须在没有选择任何内容的情况下检查(ind不能是-1 )。

+0

我想在用户单击按钮时打印D列。所以我必须这样绑定按钮:self.plot_btn.Bind(wx.EVT_BUTTON,self.OnPlot,self.plot_btn)现在,如果我按照你所说的那样定义onplot,它会给我错误CommandEvent没有属性'GetIndex ' –

+0

因为你说你的绑定语句是'self.Bind(wx.EVT_LIST_ITEM_SELECTED,self.OnPlot,self.list)'我假定点击发生在'ListCtrl'' self.list'上,因为按钮没有有一个'事件',而ListCtrl呢。你将不得不发布你的代码,而不仅仅是这个片段。我想你必须得到按钮事件来激发一个'listCtrl'事件,这是一种奇怪的方式来安排事情,但不是不可能做到。 –

+0

看到我编辑的答案 –

0

在我看来,列表控件有点难以使用。基本上你需要让你在硬代码哪一列你有兴趣在这样的事情应该让你开始哪一行:

import wx 


class MyForm(wx.Frame): 

    def __init__(self): 
     wx.Frame.__init__(self, None, wx.ID_ANY, "List Control Tutorial") 

     # Add a panel so it looks the correct on all platforms 
     panel = wx.Panel(self, wx.ID_ANY) 
     self.index = 0 
     self.current_selection = None 

     self.list_ctrl = wx.ListCtrl(panel, size=(-1,100), 
            style=wx.LC_REPORT 
         |wx.BORDER_SUNKEN 
         ) 
     self.list_ctrl.InsertColumn(0, 'Subject') 
     self.list_ctrl.InsertColumn(1, 'Due') 
     self.list_ctrl.InsertColumn(2, 'Location', width=125) 
     self.list_ctrl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.on_item_selected) 

     btn = wx.Button(panel, label="Add Line") 
     btn.Bind(wx.EVT_BUTTON, self.add_line) 

     data_getter_btn = wx.Button(panel, label='Get all data') 
     data_getter_btn.Bind(wx.EVT_BUTTON, self.on_get_data) 

     sizer = wx.BoxSizer(wx.VERTICAL) 
     sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 5) 
     sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5) 
     sizer.Add(data_getter_btn, 0, wx.ALL|wx.CENTER, 5) 
     panel.SetSizer(sizer) 

    def add_line(self, event): 
     line = "Line %s" % self.index 
     self.list_ctrl.InsertStringItem(self.index, line) 
     self.list_ctrl.SetStringItem(self.index, 1, "01/19/2010") 
     self.list_ctrl.SetStringItem(self.index, 2, "USA") 
     self.index += 1 

    def on_item_selected(self, event): 
     self.current_selection = event.m_itemIndex 

    def on_get_data(self, event): 
     if self.current_selection: 
      print self.current_selection 
      item = self.list_ctrl.GetItem(itemId=self.current_selection, col=2) 
      print item.GetText() 

#---------------------------------------------------------------------- 
# Run the program 
if __name__ == "__main__": 
    app = wx.App(False) 
    frame = MyForm() 
    frame.Show() 
    app.MainLoop() 

上面的代码将打印出当前选择(行号)和第三栏的文字。如果你想打印出所有的行和列的文本,那么你可以做这样的事情:

import wx 

######################################################################## 
class MyForm(wx.Frame): 

    #---------------------------------------------------------------------- 
    def __init__(self): 
     wx.Frame.__init__(self, None, wx.ID_ANY, "List Control Tutorial") 

     # Add a panel so it looks the correct on all platforms 
     panel = wx.Panel(self, wx.ID_ANY) 
     self.index = 0 

     self.list_ctrl = wx.ListCtrl(panel, size=(-1,100), 
         style=wx.LC_REPORT 
         |wx.BORDER_SUNKEN 
         ) 
     self.list_ctrl.InsertColumn(0, 'Subject') 
     self.list_ctrl.InsertColumn(1, 'Due') 
     self.list_ctrl.InsertColumn(2, 'Location', width=125) 

     btn = wx.Button(panel, label="Add Line") 
     btn2 = wx.Button(panel, label="Get Data") 
     btn.Bind(wx.EVT_BUTTON, self.add_line) 
     btn2.Bind(wx.EVT_BUTTON, self.get_data) 

     sizer = wx.BoxSizer(wx.VERTICAL) 
     sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 5) 
     sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5) 
     sizer.Add(btn2, 0, wx.ALL|wx.CENTER, 5) 
     panel.SetSizer(sizer) 

    #---------------------------------------------------------------------- 
    def add_line(self, event): 
     line = "Line %s" % self.index 
     self.list_ctrl.InsertStringItem(self.index, line) 
     self.list_ctrl.SetStringItem(self.index, 1, "01/19/2010") 
     self.list_ctrl.SetStringItem(self.index, 2, "USA") 
     self.index += 1 

    #---------------------------------------------------------------------- 
    def get_data(self, event): 
     """""" 
     count = self.list_ctrl.GetItemCount() 
     cols = self.list_ctrl.GetColumnCount() 
     for row in range(count): 
      for col in range(cols): 
       item = self.list_ctrl.GetItem(itemId=row, col=col) 
       print item.GetText() 

#---------------------------------------------------------------------- 
# Run the program 
if __name__ == "__main__": 
    app = wx.App(False) 
    frame = MyForm() 
    frame.Show() 
    app.MainLoop() 

更简单的方法来完成这样的事情,虽然将物体与每一行相关联。这里有一个例子:

import wx 

######################################################################## 
class Car(object): 
    """""" 

    #---------------------------------------------------------------------- 
    def __init__(self, make, model, year, color="Blue"): 
     """Constructor""" 
     self.make = make 
     self.model = model 
     self.year = year 
     self.color = color 


######################################################################## 
class MyPanel(wx.Panel): 
    """""" 

    #---------------------------------------------------------------------- 
    def __init__(self, parent): 
     """Constructor""" 
     wx.Panel.__init__(self, parent) 

     rows = [Car("Ford", "Taurus", "1996"), 
       Car("Nissan", "370Z", "2010"), 
       Car("Porche", "911", "2009", "Red") 
       ] 

     self.list_ctrl = wx.ListCtrl(self, size=(-1,100), 
           style=wx.LC_REPORT 
           |wx.BORDER_SUNKEN 
           ) 
     self.list_ctrl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onItemSelected) 
     self.list_ctrl.InsertColumn(0, "Make") 
     self.list_ctrl.InsertColumn(1, "Model") 
     self.list_ctrl.InsertColumn(2, "Year") 
     self.list_ctrl.InsertColumn(3, "Color") 

     index = 0 
     self.myRowDict = {} 
     for row in rows: 
      self.list_ctrl.InsertStringItem(index, row.make) 
      self.list_ctrl.SetStringItem(index, 1, row.model) 
      self.list_ctrl.SetStringItem(index, 2, row.year) 
      self.list_ctrl.SetStringItem(index, 3, row.color) 
      self.myRowDict[index] = row 
      index += 1 

     sizer = wx.BoxSizer(wx.VERTICAL) 
     sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 5) 
     self.SetSizer(sizer) 

    #---------------------------------------------------------------------- 
    def onItemSelected(self, event): 
     """""" 
     currentItem = event.m_itemIndex 
     car = self.myRowDict[currentItem] 
     print car.make 
     print car.model 
     print car.color 
     print car.year 

######################################################################## 
class MyFrame(wx.Frame): 
    """""" 

    #---------------------------------------------------------------------- 
    def __init__(self): 
     """Constructor""" 
     wx.Frame.__init__(self, None, wx.ID_ANY, "List Control Tutorial") 
     panel = MyPanel(self) 
     self.Show() 

#---------------------------------------------------------------------- 
if __name__ == "__main__": 
    app = wx.App(False) 
    frame = MyFrame() 
    app.MainLoop() 

很坦率地说,我真的不再使用ListCtrl了。我更喜欢使用ObjectListView,因为它看起来更容易使用,并提供了更多的功能。这里有几个环节: