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

Создание диалога из файла

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

Автор оригинала: Mike Driscoll.

Несколько дней назад я написал статью об использовании Configurehj с Wxpython. Первый вопрос, который мне задали вопрос об статье, рассматриваемой с использованием файла конфигурации для генерации диалога. Я думал, что это интересная идея, поэтому я взял на себя удар при реализации этой функциональности. Лично я думаю, что, вероятно, будет лучше просто создать диалог, используя XRC и использовать ConfigObj, чтобы помочь управлять тем, какой диалоговый файл загружен таким образом. Однако это было интригующее упражнение для меня, и я думаю, что вы найдете его тоже.

Отказ от ответственности: Это общий взлом и может или не может служить вам потребностей. Я даю различные предложения для расширения примера, хотя, поэтому я надеюсь, что это полезно!

Теперь, когда это выходит из пути, давайте создадим супер простой файл конфигурации. Мы назовем это «config.ini» для удобства:

config.ini.

[Labels]
server = Update Server:
username = Username:
password = Password:
update interval = Update Interval:
agency = Agency Filter:
filters = ""

[Values]
server = http://www.someCoolWebsite/hackery.php
username = ""
password = ""
update interval = 2
agency_choices = Include all agencies except, Include all agencies except, Exclude all agencies except
filters = ""

Этот файл конфигурации имеет два раздела: этикетки и значения. Этикетки В разделе есть этикетки, которые мы будем использовать для создания элементов управления WX.Statictext с. Значения Раздел имеет некоторые значения образцов, которые мы можем использовать для соответствующих виджетов для управления текстовыми элементами и одной коробкой со списком. Обратите внимание, что agent_choices Поле – это список. Первый элемент в списке будет вариантом по умолчанию в поле Combo, а два других элемента являются реальным содержимым виджета.

Теперь давайте посмотрим на код, который построит диалог:

preferencesDlg.py

import configobj
import wx

########################################################################
class PreferencesDialog(wx.Dialog):
    """
    Creates and displays a preferences dialog that allows the user to
    change some settings.
    """

    #----------------------------------------------------------------------
    def __init__(self):
        """
        Initialize the dialog
        """
        wx.Dialog.__init__(self, None, wx.ID_ANY, 'Preferences', size=(550,300))
        self.createWidgets()
        
    #----------------------------------------------------------------------
    def createWidgets(self):
        """
        Create and layout the widgets in the dialog
        """
        lblSizer = wx.BoxSizer(wx.VERTICAL)
        valueSizer = wx.BoxSizer(wx.VERTICAL)
        btnSizer = wx.StdDialogButtonSizer()
        colSizer = wx.BoxSizer(wx.HORIZONTAL)
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        
        iniFile = "config.ini"
        self.config = configobj.ConfigObj(iniFile)
        
        labels = self.config["Labels"]
        values = self.config["Values"]
        self.widgetNames = values
        font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.BOLD)
        
        for key in labels:
            value = labels[key]
            lbl = wx.StaticText(self, label=value)
            lbl.SetFont(font)
            lblSizer.Add(lbl, 0, wx.ALL, 5)
            
        for key in values:
            print key
            value = values[key]
            if isinstance(value, list):
                default = value[0]
                choices = value[1:]
                cbo = wx.ComboBox(self, value=value[0],
                                  size=wx.DefaultSize, choices=choices, 
                                  style=wx.CB_DROPDOWN|wx.CB_READONLY, 
                                  name=key)
                valueSizer.Add(cbo, 0, wx.ALL, 5)
            else:
                txt = wx.TextCtrl(self, value=value, name=key)
                valueSizer.Add(txt, 0, wx.ALL|wx.EXPAND, 5)
                
        saveBtn = wx.Button(self, wx.ID_OK, label="Save")
        saveBtn.Bind(wx.EVT_BUTTON, self.onSave)
        btnSizer.AddButton(saveBtn)
        
        cancelBtn = wx.Button(self, wx.ID_CANCEL)
        btnSizer.AddButton(cancelBtn)
        btnSizer.Realize()
        
        colSizer.Add(lblSizer)
        colSizer.Add(valueSizer, 1, wx.EXPAND)
        mainSizer.Add(colSizer, 0, wx.EXPAND)
        mainSizer.Add(btnSizer, 0, wx.ALL | wx.ALIGN_RIGHT, 5)
        self.SetSizer(mainSizer)
        
    #----------------------------------------------------------------------
    def onSave(self, event):
        """
        Saves values to disk
        """
        for name in self.widgetNames:
            widget = wx.FindWindowByName(name)
            if isinstance(widget, wx.ComboBox):
                selection = widget.GetValue()
                choices = widget.GetItems()
                choices.insert(0, selection)
                self.widgetNames[name] = choices
            else:
                value = widget.GetValue()
                self.widgetNames[name] = value
        self.config.write()
        self.EndModal(0)
        
########################################################################
class MyApp(wx.App):
    """"""

    #----------------------------------------------------------------------
    def OnInit(self):
        """Constructor"""
        dlg = PreferencesDialog()
        dlg.ShowModal()
        dlg.Destroy()
        
        return True
        
if __name__ == "__main__":
    app = MyApp(False)
    app.MainLoop()

Для начала мы подкласс wx.dialog и все это Createwidgets метод. Этот метод будет прочитать наш файл конфигурации и использовать в нем данные, чтобы создать дисплей. После того, как конфиг будет прочитан, мы петлю по клавишам в Этикетки Раздел и создайте статический элемент управления текстом по мере необходимости. Далее мы цикла по ценам в другом разделе и используем условный для проверки типа виджета. В этом случае мы заботимся только о wx.textctrl и wx.combobox. Это где Configobj помогает, поскольку на самом деле он может пописать некоторые записи в нашем файле конфигурации. Если вы используете ConfigSpec, вы можете получить еще более гранулированные, и это может быть то, как вы захотите продлить это руководство. Обратите внимание, что для текстовых элементов управления и комбинированного поле я устанавливаю поле имени. Это важно для сохранения данных, которые мы увидимся в мгновение.

Во всяком случае, в обеих петлях мы используем вертикальные боксы для удержания наших виджетов. Возможно, вы захотите поменять это для GreeBagsizer или FLEXGRIDSIZER для вашего специализированного интерфейса. Я лично очень люблю Boxsizer. Я также использовал stddialogbuttonsizer для кнопок по предложению Стивена SPROAT ( isteboard ). Если вы используете правильные стандартные идентификаторы для кнопок, этот Sizer поместит их в правильном порядке на перекрестном платформе. Это довольно удобно, хотя он не принимает много аргументов. Также обратите внимание, что Документация Для этого Sizer подразумевает, что вы можете указать ориентацию, но вы действительно не можете. Я говорил с Робином Данном (создателем WXPYPHON) об этом вопросе на IRC, и он сказал, что Epydoc хватал не ту документ.

Следующий метод, который мы заботимся о том, это Onsave Отказ Вот где мы сохраняем все, что пользователь ввел. Ранее в программе я схватил названия виджетов из конфигурации, и мы сейчас циклируемся. Мы называем wx.findwindowbyname, чтобы найти виджет по имени. Тогда мы используем Isinstance Опять же, чтобы проверить, какой виджет у нас есть. Как только это сделано, мы получаем значение того, что виджет имеет использование GetWalue и назначить это значение в правильное поле в нашей конфигурации. Когда петли заканчивается, мы пишем данные на диск. Немедленное улучшение Alert: у меня нет проверки здесь вообще! Это то, что вам нужно сделать, чтобы продлить этот пример Отказ Последний шаг – звонить в EndModal (0), чтобы закрыть диалоговое окно и, в свою очередь, приложение.

Теперь вы знаете основы генерации диалога из файла конфигурации. Я думаю, что используя какой-то словарь с именами типа виджетов (вероятно, в строках) может быть простой способ сделать этот сценарий работать с другими виджетами. Используйте свое воображение и дайте мне знать, что вы придумаете.

ПРИМЕЧАНИЕ. Вся код протестирован на Windows XP с Python 2.5, ConfigObj 4.6.0 и Validate 1.0.0.

Дальнейшее чтение

Загрузки

  • dialog_from_config.zip
  • dialog_from_config.tar.