2

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

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

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

4

2 回答 2

4

该事件将从 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 )。

于 2017-06-23T14:57:00.363 回答
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,因为它看起来更容易使用并且提供了更多开箱即用的功能。这里有几个链接:

于 2017-06-23T14:00:38.887 回答