2017-06-23 13 views
1

J'ai un wxpython listctrl, qui contient 4 colonnes [A, B, C, D]. L'utilisateur sélectionne l'une des lignes de listctrl. Maintenant, j'ai un bouton dans mon interface graphique, donc quand je clique sur ce que je veux imprimer la valeur de la colonne D de cette ligne sélectionnée. Par exemple permet à l'utilisateur a sélectionné cette ligne:
[PYTHON, JAVA, Matlab, RUBY]
maintenant si l'utilisateur clique sur le bouton, il doit donner sortie: RUBY
Je lient le bouton dans cette façonComment lier wxpython listctrl avec un événement de bouton 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 

Et événement OnPlot j'ai défini comme: def OnPlot(self, event): click = event.GetText()

Cela ne fonctionne pas mais. Comment puis-je accomplir cela?

Répondre

2

L'événement passera l'index de l'élément sélectionné de la listctrl.
Utilisez l'index pour obtenir l'élément et la colonne dans le listctrl, dans ce cas 3.
Récupérez le texte de la colonne.
A savoir:

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

Cela suppose que vous avez lié le listctrl comme ceci:

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

Edit:
En ce qui concerne votre commentaire et le modifier au titre de la question. Vous ne pouvez pas lier un événement arbitraire à quelque chose. Un bouton a un ensemble d'événements définis comme le fait un listctrl et jamais le twain ne doit se rencontrer. Le moyen de contourner votre problème consiste à lier le bouton à un événement de bouton.

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

puis définissez on_plot comme ceci:

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

Comme vous le verrez le même résultat final, mais il est un grand mais, vous avez déjà dû cliquer sur le listctrl pour sélectionner un élément . Dans ce cas, vous auriez déjà obtenu le même résultat, en utilisant la première méthode, sans avoir à définir le bouton et en utilisant cette méthode, vous devez maintenant vérifier si rien n'a été sélectionné (ind ne doit pas être -1).

+0

Je veux imprimer la colonne D lorsque l'utilisateur clique sur le bouton. Donc, je dois lier le bouton de cette façon: self.plot_btn.Bind (wx.EVT_BUTTON, self.OnPlot, self.plot_btn) Maintenant, si je définis onplot de cette façon que vous l'avez dit, cela me donne une erreur CommandEvent n'a pas d'attribut 'GetIndex ' –

+0

Parce que vous avez dit que votre instruction de liaison était 'self.Bind (wx.EVT_LIST_ITEM_SELECTED, self.OnPlot, self.list)' j'ai supposé que le clic se produisait sur le 'ListCtrl'' self.list' comme un bouton ne avoir cet 'event' alors qu'un' ListCtrl' le fait. vous devrez poster votre code et pas seulement cet extrait. Je suppose que vous deviez obtenir l'événement button pour déclencher un événement 'listCtrl' qui est une étrange façon d'arranger les choses mais pas impossible à faire. –

+0

Voir ma réponse éditée –

0

Le contrôle de la liste est difficile à utiliser selon moi. Fondamentalement, vous aurez besoin pour obtenir ce que la ligne que vous êtes et coder en dur ce que la colonne que vous êtes intéressé par quelque chose comme cela devrait vous aider à démarrer.

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() 

Le code ci-dessus imprimer la sélection en cours (numéro de ligne) et le texte de la 3ème colonne. Si vous voulez imprimer toutes les lignes et le texte de la colonne, vous pouvez faire quelque chose comme ceci:

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() 

Un moyen plus facile d'accomplir ce genre de chose mais serait d'associer des objets à chaque rangée. Voici un exemple:

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() 

Très franchement, je n'utilise plus vraiment le ListCtrl. Je préfère utiliser ObjectListView car il semble plus facile à utiliser et offre beaucoup plus de fonctionnalités. Voici quelques liens: