Генерация групп виджетов wxPython из списков - PullRequest
2 голосов
/ 14 сентября 2011

Это один из тех вопросов, которые мне очень неприятно задавать, потому что я уверен, что ответ там есть, я просто не смог правильно сформулировать результаты поиска.По сути, я новичок в программировании с графическим интерфейсом (сделал много встроенного C / C ++) и изучаю wxPython для начала.

Я делаю приложение для чтения и записи в файл конфигурации.Таким образом, у меня есть StaticText для отображения имени параметра, который нужно прочитать / записать, TextCtrl для отображения значения и разрешения ввода пользователя, а затем кнопка Get и кнопка Set.Я буду называть все это вместе "группой" виджетов.Для этого приложения, очевидно, эта группа будет повторяться несколько раз.Вместо того чтобы писать и поддерживать весь этот код вручную, я подумал, что будет проще просто получить список параметров конфигурации, которые я хочу иметь возможность редактировать, а затем выполнить итерацию по списку и сгенерировать экземпляр этой «группы»виджеты для каждого элемента в списке.Я сделал это, за исключением одного: мне пришлось привязать все кнопки Get к одной и той же функции.То же самое с кнопками Set.Есть ли какой-либо способ из этих функций узнать, какая кнопка «Получить» или «Установить» была нажата, и, следовательно, какой параметр найти и изменить в файле конфигурации?Я уверен, что есть способ сделать это с помощью родителя, идентификаторов или чего-то еще, но я слишком плохо знаком с ООП.

Ответы [ 3 ]

2 голосов
/ 14 сентября 2011

Я предполагаю, что кнопка get считывает значение параметра из файла конфигурации и отображает значение.

Зачем вам нужна одна кнопка get для каждого параметра?У меня была бы только одна кнопка «получить» для всех.Когда пользователь нажимает кнопку «получить», каждый параметр считывается из файла, и все дисплеи обновляются.

Аналогичный подход для кнопки установки.Одна кнопка установки для них всех - при нажатии кнопки каждый параметр, для которого введено новое значение, обновляется в файле конфигурации.Параметры, в которых пользователь не ввел новое значение, остаются с его предыдущими значениями.

Эта схема проще для кодирования и также проще для пользователя.

Однако я действительно предлагаю вам взглянуть на wxPropertyGrid виджет.Это может сделать вашу жизнь намного проще!Вот скриншот, показывающий один в действии

enter image description here

1 голос
/ 14 сентября 2011

В обработчике событий вашей кнопки вы можете сделать что-то вроде этого:

btn = event.GetEventObject()
btn.GetId()
btn.GetName()

Тогда вы просто используете оператор If, чтобы решить, что делать, основываясь на любой информации, которую вы хотите использовать. Примечание: вы можете установить имя кнопки при ее создании следующим образом:

setBtn = wx.Button(self, label="Set", name="SetX")

Эта статья по wxPython и ConfigObj может оказаться полезной: http://www.blog.pythonlibrary.org/2010/01/17/configobj-wxpython-geek-happiness/

0 голосов
/ 15 сентября 2011

Вы можете получить свой собственный класс из wx.Button и добавить к нему один или несколько атрибутов, чтобы кнопка помнила любую информацию, которую вы хотите.

Вы можете использовать эту сохраненную информацию во время вызова функции обратного вызова.Что-то вроде:

import wx

L = [("1", "One"), ("2", "Two"), ("3", "Three")]

# =====================================================================
class MemoryButton(wx.Button):
    def __init__(self, memory, *args, **kwargs):
        wx.Button.__init__(self, *args, **kwargs)
        self.memory = memory

# =====================================================================
class MainWindow(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        self.panel = wx.Panel(self)
        self.buttons = []
        for description in L:
            button = MemoryButton(memory=description[1], parent=self.panel,
                                  label=description[0])
            button.Bind(wx.EVT_BUTTON, self.OnMemoryButton)
            self.buttons.append(button)

        self.sizer = wx.BoxSizer()
        for button in self.buttons:
            self.sizer.Add(button)

        self.panel.SetSizerAndFit(self.sizer)  
        self.Show()

    # -----------------------------------------------------------------
    def OnMemoryButton(self, e):
        print("Clicked '%s'" % e.GetEventObject().memory)

# =====================================================================
app = wx.App(False)
win = MainWindow(None)
app.MainLoop()

или альтернативно:

import wx

L = [("1", "One"), ("2", "Two"), ("3", "Three")]

# =====================================================================
class MemoryButton(wx.Button):
    def __init__(self, memory, *args, **kwargs):
        wx.Button.__init__(self, *args, **kwargs)
        self.memory = memory

    def OnButton(self, e):
        print("Clicked '%s'" % self.memory)

# =====================================================================
class MainWindow(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        self.panel = wx.Panel(self)
        self.buttons = []
        for description in L:
            button = MemoryButton(memory=description[1], parent=self.panel,
                                  label=description[0])
            button.Bind(wx.EVT_BUTTON, button.OnButton)
            self.buttons.append(button)

        self.sizer = wx.BoxSizer()
        for button in self.buttons:
            self.sizer.Add(button)

        self.panel.SetSizerAndFit(self.sizer)  
        self.Show()

# =====================================================================
app = wx.App(False)
win = MainWindow(None)
app.MainLoop()
...