2017-06-23 43 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,因爲它看起來更容易使用,並提供了更多的功能。這裏有幾個環節: