Автор оригинала: Mike Driscoll.
Ранее на этой неделе было обсуждение канала WXPYPHON IRC о том, как хранить объекты в WX.Listbox. Потом позже в тот день возник вопрос о Stackoverflow о том же, но по отношению к wx.combobox. К счастью, оба этих виджета наследуют от WX.Itemcontainer и содержат метод Append, который позволяет связать объект с элементом в этих виджетах. В этой статье вы узнаете, как это сделано.
Добавление объектов в wx.listbox
Мы начнем с ListBox сначала. Давайте просто прыгнем в код, как я думаю, вы узнаете его быстрее таким образом.
import wx class Car: """""" def __init__(self, id, model, make, year): """Constructor""" self.id = id self.model = model self.make = make self.year = year class MyForm(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, wx.ID_ANY, "Tutorial") # Add a panel so it looks the correct on all platforms panel = wx.Panel(self, wx.ID_ANY) cars = [Car(0, "Ford", "F-150", "2008"), Car(1, "Chevrolet", "Camaro", "2010"), Car(2, "Nissan", "370Z", "2005")] sampleList = [] self.cb = wx.ComboBox(panel, size=wx.DefaultSize, choices=sampleList) self.widgetMaker(self.cb, cars) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.cb, 0, wx.ALL, 5) panel.SetSizer(sizer) def widgetMaker(self, widget, objects): """""" for obj in objects: widget.Append(obj.make, obj) widget.Bind(wx.EVT_COMBOBOX, self.onSelect) def onSelect(self, event): """""" print("You selected: " + self.cb.GetStringSelection()) obj = self.cb.GetClientData(self.cb.GetSelection()) text = """ The object's attributes are: %s %s %s %s """ % (obj.id, obj.make, obj.model, obj.year) print(text) # Run the program if __name__ == "__main__": app = wx.App(False) frame = MyForm() frame.Show() app.MainLoop()
Теперь, как эта работа? Давайте займем некоторое время и распакуйте этот пример. Во-первых, мы создаем супер-простой класс автомобиля, где мы определяем четыре атрибута: идентификатор, модель, производитель и год. Затем мы создаем простую рамку с панелью и ListBox виджет. Как видите, мы используем унаследованную способ наследования Playbox, чтобы добавить строку каждого объекта автомобиля, а затем сам объект. Это позволяет нам ассоциировать каждый элемент в поле списка к объекту. Наконец, мы связываем список для Evt_listbox Таким образом, мы можем узнать, как получить доступ к этому объекту, когда мы выбираем элемент из виджета.
Чтобы увидеть, как это достигнуто, проверьте onselect метод. Здесь мы видим, что нам нужно позвонить в список GetClientData Способ и пропустите его текущий выбор. Это вернет объект, который мы ассоциировали ранее. Теперь мы можем получить доступ к каждому из атрибутов метода. В этом примере мы просто распечатаем все это на STDOUT. Теперь давайте посмотрим, как это сделано с wx.combobox.
Добавление объектов к wx.combobox
Код для wx.combobox практически одинаково, поэтому для удовольствия мы сделаем небольшой рефакторинг. Взглянуть:
import wx class Car: """""" def __init__(self, id, model, make, year): """Constructor""" self.id = id self.model = model self.make = make self.year = year class MyForm(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, wx.ID_ANY, "Tutorial") # Add a panel so it looks the correct on all platforms panel = wx.Panel(self, wx.ID_ANY) cars = [Car(0, "Ford", "F-150", "2008"), Car(1, "Chevrolet", "Camaro", "2010"), Car(2, "Nissan", "370Z", "2005")] sampleList = [] self.cb = wx.ComboBox(panel, size=wx.DefaultSize, choices=sampleList) self.widgetMaker(self.cb, cars) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.cb, 0, wx.ALL, 5) panel.SetSizer(sizer) def widgetMaker(self, widget, objects): """""" for obj in objects: widget.Append(obj.make, obj) widget.Bind(wx.EVT_COMBOBOX, self.onSelect) def onSelect(self, event): """""" print("You selected: " + self.cb.GetStringSelection()) obj = self.cb.GetClientData(self.cb.GetSelection()) text = """ The object's attributes are: %s %s %s %s """ % (obj.id, obj.make, obj.model, obj.year) print(text) # Run the program if __name__ == "__main__": app = wx.App(False) frame = MyForm() frame.Show() app.MainLoop()
В этом примере этапы точно одинаковы. Но что у нас были несколько комбайнов, которые мы должны были сделать такую вещь? Это было бы много избыточного кода. Таким образом, мы записали простой помощник методом под названием WidgetMaker Это привязывает приложение и событие для нас. Мы могли бы построить виджет, добавить его в Sizer и другие вещи, но мы будем держать это просто для этого примера. Во всяком случае, чтобы он работал, мы проходим в виджете Combobox вместе со списком объектов, которые мы хотим добавить в виджет. WidgetMaker будет добавлять эти объекты в Combobox для нас. Остальная часть кода одинакова, за исключением незначительного другого события, к которому нам нужно было привязать.
Обертывание
Как видите, это довольно прямое упражнение, но это делает ваш GUI более надежным. Вы можете сделать это для приложений базы данных. Я вижу, используя это с наборами результатов SQLALCHEMY. Будьте креативны, и я уверен, что вы найдете хорошее использование для этого.
Дополнительное чтение
- wx.itemcontainer документация
- wx.combobox документация
- wx.listbox документация