Эта статья появилась в результате обсуждения на IRC-канале wxPython, темой которой было помещение объектов в wx.ListBox. Позже, в этой же день, я наткнулся на аналогичный вопрос на StackOverflow, только там речь шла уже о wx.ComboBox. К счастью, оба эти виждета являются наследниками wx.ItemContainer и содержат метод Append, который позволяет вам ассоциировать объект с итемом в этих виджетах. Сейчас я расскажу вам как это делается!
Добавляем объекты в wx.ListBox
Мы начнём с ListBox. Сразу переходи к коду, я думаю, что так вам будет проще понять происходящее.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
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, title="Tutorial") 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) if __name__ == "__main__": app = wx.App(False) frame = MyForm() frame.Show() app.MainLoop() |
Теперь к тому, как это работает. Давайте потратим немного времени и в деталях разберём предложенный мной пример. Во-первых, мы создаём сверх-простой класс Car, в котором мы обозначаем четыре атрибута: id, модель, марку и год. Затем мы создаём простую рамку с панелью, на которой расположен виджет ListBox.
Как вы видите, мы используем унаследованный им метод, который называется Append, чтобы добавить к объекту «Марка» стринг, а потом уже и сам объект. Наконец, мы биндим ListBox к EVT_LISTBOX, чтобы мы могли понять, как получит доступ к объекту, когда мы выбираем итем из виджета.
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Чтобы увидеть полную картинку, вам нужно ознакомиться с методом onSelect. Здесь мы можем увидеть, что нам нужно вызвать метод ListBox, который называется GetClientData и пропустить через него данные из текущей секции. Это вернёт объект, с которым мы ассоциировали ранее. Теперь мы получает доступ ко всем атрибутам метода. В нашем примере, мы просто печатаем это всё в stdout. Теперь давайте узнаем, как сделать то же самое, но используя wx.ComboBox.
Добавляем объекты в wx.ComboBox
Код для wx.ComboBox практический такой же, поэтому, забавы ради, мы его немного переработаем. Взгляните:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
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, title="ListBox Obj Tutorial") panel = wx.Panel(self, wx.ID_ANY) ford = Car(0, "Ford", "F-150", "2008") chevy = Car(1, "Chevrolet", "Camaro", "2010") nissan = Car(2, "Nissan", "370Z", "2005") sampleList = [] lb = wx.ListBox(panel, size=wx.DefaultSize, choices=sampleList) self.lb = lb lb.Append(ford.make, ford) lb.Append(chevy.make, chevy) lb.Append(nissan.make, nissan) lb.Bind(wx.EVT_LISTBOX, self.onSelect) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(lb, 0, wx.ALL, 5) panel.SetSizer(sizer) def onSelect(self, event): """""" selection = self.lb.GetStringSelection() if selection: print("You selected: " + selection) obj = self.lb.GetClientData(self.lb.GetSelection()) text = """ The object's attributes are: %s %s %s %s """ % (obj.id, obj.make, obj.model, obj.year) print(text) if __name__ == "__main__": app = wx.App(False) frame = MyForm() frame.Show() app.MainLoop() |
В данном примере, шаги точь-в-точь такие же, как и в предыдущем. Но что нам делать в случае, когда у на нас несколько ComboBox? Будет очень много лишнего кода. Таким образом, нам нужно написать простой вспомогательный метод, который называется widgetMaker, который сам выделит события и забиндит их вместо нас.
Мы можем заставить его встраивать виджеты, добавлять их в сайзеры, и ещё многое другое, но нашего примера это не касается вовсе. Как бы то ни было, чтобы всё заработало, мы пропускаем через виджет ComboBox список объектов, которые мы хотим добавить в этот виджет. widgetMaker выделит все эти объекты и перенесёт их в ComboBox вместо нас. В остальном – код полностью идентичен прошлому примеру, различие лишь в событии, к которому нам нужно было всё это привязать.
Итоги
Как вы могли заметить, это весьма прямолинейное маленькое упражнение, но оно делает интерфейс вашего приложения более простым и понятным для конечного пользователя. Эти знания можно использовать при создании приложений баз данных. Я чётко вижу, как совместить это с наборами результатов SqlAlchemy. Будьте креативными и, я уверен, вы найдёте ещё массу применений для данных умений!
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»