В этой статье мы рассмотрим Wizard-виджет wxPython. Нет, это не имеет ничего общего с Дамблдором или Гэндальфом. Вместо этого это тот диалог, который вы увидите при запуске установщика или настройке шаблона. Иногда вы даже увидите, как они используются для настройки слияния. В этом уроке мы рассмотрим два примера: один довольно простой, а другой немного более сложный. Давайте начнем!
Примечание: код в этой статье был адаптирован из демонстрационного приложения wxPython
Простой Мастер
Когда вам нужно использовать мастер в wxPython, вам нужно импортировать его особым образом. Вместо того, чтобы просто импортировать wx , вы должны будете сделать это: import wx.wizard . Также обратите внимание, что существует два основных типа страниц мастера: WizardPageSimple и PyWizardPage. Первый самый простой, поэтому мы будем использовать его в нашем простом примере. Вот код:
import wx import wx.wizard as wiz ######################################################################## class TitledPage(wiz.WizardPageSimple): """""" #---------------------------------------------------------------------- def __init__(self, parent, title): """Constructor""" wiz.WizardPageSimple.__init__(self, parent) sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(sizer) title = wx.StaticText(self, -1, title) title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD)) sizer.Add(title, 0, wx.ALIGN_CENTRE|wx.ALL, 5) sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 5) #---------------------------------------------------------------------- def main(): """""" wizard = wx.wizard.Wizard(None, -1, "Simple Wizard") page1 = TitledPage(wizard, "Page 1") page2 = TitledPage(wizard, "Page 2") page3 = TitledPage(wizard, "Page 3") page4 = TitledPage(wizard, "Page 4") wx.wizard.WizardPageSimple.Chain(page1, page2) wx.wizard.WizardPageSimple.Chain(page2, page3) wx.wizard.WizardPageSimple.Chain(page3, page4) wizard.FitToPage(page1) wizard.RunWizard(page1) wizard.Destroy() #---------------------------------------------------------------------- if __name__ == "__main__": app = wx.App(False) main() app.MainLoop()
Это довольно много кода. Давайте возьмем это на себя и посмотрим, сможем ли мы это выяснить. Прежде всего, мы импортируем wx и мастер, который мы переименуем в «wiz», чтобы сэкономить на нажатиях клавиш. Затем мы создаем класс TitledPage, который подклассов WizardPageSimple . Этот класс будет основой для всех страниц нашего мастера. Он в основном просто определяет страницу с центрированным заголовком 18-точечным шрифтом со строкой внизу.
В основной функции мы находим настоящее мясо. Здесь мы создаем мастер, используя следующий синтаксис: wx.wizard.Wizard (Нет, -1, «Простой мастер») . Это дает мастеру родителя None, идентификатор и название. Затем мы создаем четыре страницы, которые являются экземплярами класса TitledPage, о котором мы упоминали ранее. Наконец, мы используем wx.wizard.WizardPageSimple.Chain, чтобы связать страницы вместе. Это позволяет нам использовать пару автоматически сгенерированных кнопок для перемещения по страницам вперед и назад. Последняя пара строк кода запустит мастер и, когда пользователь закончит, уничтожит мастер. Довольно просто, правда? Теперь давайте перейдем к более сложному примеру.
Использование PyWizardPage
В этом разделе мы создадим подкласс PyWizardPage . У нас также будет подкласс WizardPageSimple, чтобы мы могли смешивать и сочетать их, чтобы создать серию разных страниц. Давайте просто перейдем к коду, чтобы вы могли убедиться в этом сами!
import images import wx import wx.wizard as wiz ######################################################################## class TitledPage(wiz.WizardPageSimple): """""" #---------------------------------------------------------------------- def __init__(self, parent, title): """Constructor""" wiz.WizardPageSimple.__init__(self, parent) sizer = wx.BoxSizer(wx.VERTICAL) self.sizer = sizer self.SetSizer(sizer) title = wx.StaticText(self, -1, title) title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD)) sizer.Add(title, 0, wx.ALIGN_CENTRE|wx.ALL, 5) sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 5) ######################################################################## class UseAltBitmapPage(wiz.PyWizardPage): #---------------------------------------------------------------------- def __init__(self, parent, title): wiz.PyWizardPage.__init__(self, parent) self.next = self.prev = None self.sizer = wx.BoxSizer(wx.VERTICAL) title = wx.StaticText(self, label=title) title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD)) self.sizer.Add(title) self.sizer.Add(wx.StaticText(self, -1, "This page uses a different bitmap"), 0, wx.ALL, 5) self.sizer.Layout() #---------------------------------------------------------------------- def SetNext(self, next): self.next = next #---------------------------------------------------------------------- def SetPrev(self, prev): self.prev = prev #---------------------------------------------------------------------- def GetNext(self): return self.next #---------------------------------------------------------------------- def GetPrev(self): return self.prev #---------------------------------------------------------------------- def GetBitmap(self): # You usually wouldn't need to override this method # since you can set a non-default bitmap in the # wxWizardPageSimple constructor, but if you need to # dynamically change the bitmap based on the # contents of the wizard, or need to also change the # next/prev order then it can be done by overriding # GetBitmap. return images.WizTest2.GetBitmap() #---------------------------------------------------------------------- def main(): """""" wizard = wiz.Wizard(None, -1, "Dynamic Wizard", images.WizTest1.GetBitmap()) page1 = TitledPage(wizard, "Page 1") page2 = TitledPage(wizard, "Page 2") page3 = TitledPage(wizard, "Page 3") page4 = UseAltBitmapPage(wizard, "Page 4") page5 = TitledPage(wizard, "Page 5") wizard.FitToPage(page1) page5.sizer.Add(wx.StaticText(page5, -1, "\nThis is the last page.")) # Set the initial order of the pages page1.SetNext(page2) page2.SetPrev(page1) page2.SetNext(page3) page3.SetPrev(page2) page3.SetNext(page4) page4.SetPrev(page3) page4.SetNext(page5) page5.SetPrev(page4) wizard.GetPageAreaSizer().Add(page1) wizard.RunWizard(page1) wizard.Destroy() #---------------------------------------------------------------------- if __name__ == "__main__": app = wx.App(False) main() app.MainLoop()
Этот код начинается так же, как и предыдущий код. В этом примере мы также импортируем модуль изображений, который содержит пару объектов PyEmbeddedImage, которые мы будем использовать, чтобы продемонстрировать, как добавлять растровые изображения на нашу страницу мастера. В любом случае, первый класс точно такой же, как и предыдущий. Затем мы создаем класс UseAltBitmapPage, который является подклассом PyWizardPage . Мы должны переопределить несколько методов, чтобы заставить его работать правильно, но они довольно очевидны. Эта страница будет использоваться только для изменения растрового изображения одной страницы.
В основной функции мы создаем мастера немного иначе, чем мы делали ранее:
wizard = wiz.Wizard(None, -1, "Dynamic Wizard", images.WizTest1.GetBitmap())
Как видите, этот метод позволяет нам добавить растровое изображение, которое появится вдоль левой стороны страниц мастера. В любом случае, после этого мы создаем пять страниц, четыре из которых являются экземплярами TitledPage, а одна — экземпляром UseAltBitmapPage . Мы подгоняем мастера к первой странице и затем видим что-то странное:
page5.sizer.Add(wx.StaticText(page5, -1, "\nThis is the last page."))
Что это делает? Ну, это глупый способ добавить виджет на страницу. Чтобы сообщить пользователю, что он достиг последней страницы, мы добавляем к нему экземпляр StaticText, который явно сообщает, что он достиг конца. Следующие несколько строк устанавливают порядок страниц, используя SetNext и SetPrev . Хотя эти методы дают вам более детальный контроль над порядком страниц, они не так удобны, как метод WizardPageSimple.Chain . Последние несколько строк кода такие же, как в предыдущем примере.
Дополнительный совет: как пометить кнопки волшебника
При создании этой статьи кто-то спросил, как изменить метки кнопок мастера в официальном списке рассылки wxPython . Поэтому для полноты картины мы примем решение Робина Данна и покажем, как изменить метки как предыдущей, так и следующей кнопки.
prev_btn = self.FindWindowById(wx.ID_BACKWARD) prev_btn.SetLabel("Foo") next_btn = self.FindWindowById(wx.ID_FORWARD) next_btn.SetLabel("Bar")
Завершение
Теперь вы знаете, как создавать мастера двух типов, включенные в wxPython. Вы также выучили забавный хак для изменения меток кнопок в мастере. Дайте мне знать, если вы думаете, что я что-то забыл, и я обновлю пост или напишу продолжение.
Дальнейшее чтение
- wx.wizard.Wizard официальная документация
- wx.wizard.WizardPage документация
- Мастер Андреа Gavana в документации
Исходный код
Источник: http://www.blog.pythonlibrary.org/2011/01/27/wxpython-a-wizard-tutorial/