Рубрики
Без рубрики

WXPYPHON: хранение объектов в классы Combobox или Listbox

Получите практические, реальные навыки Python на наших ресурсах и пути

Автор оригинала: 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. Будьте креативны, и я уверен, что вы найдете хорошее использование для этого.

Дополнительное чтение