Автор оригинала: Mike Driscoll.
Каждый теперь я вижу, как кто-то спрашивает, как получить текст для каждого элемента подряд ListCtrl в режиме отчета. Listctrl не делает это очень очевидно, как вы получите текст в строке один, столбец три, например. В этой статье мы посмотрим, как мы можем достичь этой задачи.
Получать данные из любого столбца
Давайте начнем с создания простого listctrl и используя кнопку, чтобы заполнить ее. Затем мы добавим вторую кнопку для извлечения содержимого listctrl:
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()
Давайте найдя немного, чтобы сломать этот код немного вниз. Обработчик событий первой кнопки – первая часть интересного кода. Он демонстрирует, как вставить данные в listctrl. Как вы можете видеть, это довольно просто, так как все, что нам нужно сделать, чтобы добавить ряд, называется InsertringItem а затем установите текст каждого столбца, используя SetStringItem Отказ Существуют и другие типы элементов, которые мы можем вставить в listctrl, кроме элемента строки, но это за пределами объема этой статьи.
Далее мы должны взглянуть на get_data обработчик события. Это захватывает количество ряд, используя GetItemcount метод. Мы также получаем количество столбцов в ListCTRL через GetColumnCount Отказ Наконец, мы ветер по рядам и извлеките каждую клетку, которая в плане ListCtrl известна как «элемент». Мы используем listctrl’s GetITem Способ этой задачи. Теперь, когда у нас есть товар, мы можем назвать пункт GetText
Связывание объектов к рядам
Простой способ сделать эту вещь, чтобы связать объект к каждой строке. Давайте найдя момент, чтобы увидеть, как это может быть достигнуто:
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. Посмотрите на MyPanel ‘s __init__ Способ, и вы увидите, что мы создаем список объектов строки, а затем закручивать объекты строки и вставьте их в listctrl с помощью атрибутов объекта для текстовых значений. Вы также отметите, что мы создали словарь атрибута класса, который использует для ассоциирования индекса строки к объекту автомобиля, который был вставлен в строку.
Мы также связываем listctrl to Evt_list_item_selected Поэтому, когда выбран предмет, он позвонит OniteMesebed Способ и распечатать данные из строки. Вы отметите, что мы получаем индекс ряд, используя event.m_itemindex Отказ Остальная часть кода должна быть самоизначения.
Обертывание
Теперь вы знаете пару разных подходов для извлечения всех данных из LISTCTRL. Лично мне очень нравится использовать виджет ObjectListView. Я чувствую, что превосходит listctrl, поскольку у него есть такие функции встроенные функции. Но он не включен в Wxpython, так что это дополнительная установка.
Дополнительное чтение
- Listctrl: Секреты и уловки
- WxPython: Использование ObjectListView вместо listctrl