В этой статье мы рассмотрим 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/

