<span style="font-family:Microsoft YaHei;font-size:18px;">由于wxpython自带的向导框,打包生成exe文件,向导按钮会变成英文。所以,自己动手实现了一个向导框,与大家分享。</span>
#-*- coding:utf-8 -*-
# ---------------------------------------------------------------------------#
# Name: wizard.py #
# Purpose: 向导框 <span style="white-space:pre"> </span> #
# Author: jacksmion #
# Email: jacksmion@126.com #
# Created: 2014/12/20 #
# Copyright: (c) 2014 #
#----------------------------------------------------------------------------#
import wx
# 全局变量
_= wx.GetTranslation
# 是否阻止事件下发
G_VETO = False
#-----------自定义向导框事件-----------------#
wxEVT_WIZARD_CANCEL = wx.NewEventType()
wxEVT_WIZARD_PAGE_CHANGED = wx.NewEventType()
wxEVT_WIZARD_PAGE_CHANGING = wx.NewEventType()
wxEVT_WIZARD_FINISHED = wx.NewEventType()
EVT_WIZARD_CANCEL = wx.PyEventBinder(wxEVT_WIZARD_CANCEL, 1)
EVT_WIZARD_PAGE_CHANGED = wx.PyEventBinder(wxEVT_WIZARD_PAGE_CHANGED, 1)
EVT_WIZARD_PAGE_CHANGING = wx.PyEventBinder(wxEVT_WIZARD_PAGE_CHANGING, 1)
EVT_WIZARD_FINISHED = wx.PyEventBinder(wxEVT_WIZARD_FINISHED, 1)
class PageChangeEvent(wx.PyCommandEvent):
"""
页面切换事件
"""
def __init__(self, eventType=None, win_id=0):
super(PageChangeEvent, self).__init__(eventType, win_id)
self.value = None
def SetPage(self, value):
self.value = value
def GetPage(self):
return self.value
class PageChangingEvent(wx.PyCommandEvent):
"""
页面切换事件
"""
def __init__(self, eventType=None, win_id=0):
super(PageChangingEvent, self).__init__(eventType, win_id)
self.value = None
self.isDirection = True
def SetPage(self, value):
"""
设置当前页
"""
self.value = value
def GetPage(self):
"""
获取当前页
"""
return self.value
def Veto(self):
"""
否决事件
"""
global G_VETO
G_VETO = True
def Allow(self):
"""
允许事件
"""
global G_VETO
G_VETO = False
def GetDirection(self):
"""
返回方向,如果为True,则表示向下;反之,则向上
"""
return self.isDirection
def SetDirection(self, value):
"""
设置方向,如果为True,则表示向下;反之,则向上
"""
self.isDirection = value
class WizardFinishedEvent(wx.PyCommandEvent):
"""
向导框完成事件
"""
def __init__(self, eventType=None, win_id=0):
super(WizardFinishedEvent, self).__init__(eventType, win_id)
class WizardCancelEvent(wx.PyCommandEvent):
"""
向导框取消事件
"""
def __init__(self, eventType=None, win_id=0):
super(WizardCancelEvent, self).__init__(eventType, win_id)
class Wizard(wx.Dialog):
"""
向导框
"""
def __init__(self, parent, *args, **kwargs):
super(Wizard, self).__init__(parent, *args, **kwargs)
self.parent = parent
# 布局器
self._mainSizer = wx.BoxSizer(wx.VERTICAL)
self._buttomSizer = wx.BoxSizer()
# 存放所有向导页
self.page_list = []
# 当前页
self.cur_page = None
#----------基本操作按钮----------#
self._prevBtn = wx.Button(self, -1, _(u"<上一步"))
self._nextBtn = wx.Button(self, -1, _(u"下一步>"))
self._cancelBtn = wx.Button(self, -1, _(u"取消"))
# 布局
self._doLayout()
# 事件绑定
self._doEvent()
def _doLayout(self):
"""
布局设置
"""
self._buttomSizer.Add(self._prevBtn, 0)
self._buttomSizer.Add(self._nextBtn, 0)
self._buttomSizer.Add(self._cancelBtn, 0)
self._mainSizer.Add(wx.StaticLine(self, style=wx.HORIZONTAL), 0, wx.EXPAND | wx.ALL, 10)
self._mainSizer.Add(self._buttomSizer, 0, wx.ALIGN_RIGHT | wx.ALL, 10)
self.SetSizer(self._mainSizer)
def _doEvent(self):
"""
事件绑定
"""
self.Bind(wx.EVT_BUTTON, self._OnPrev, self._prevBtn)
self.Bind(wx.EVT_BUTTON, self._OnNext, self._nextBtn)
self.Bind(wx.EVT_BUTTON, self._OnExit, self._cancelBtn)
def GetPrevBtn(self):
"""
获取上一步按钮
"""
return self._prevBtn
def GetNextBtn(self):
"""
获取下一步按钮
"""
return self._nextBtn
def _OnPrev(self, event):
"""
上一页事件
"""
global G_VETO
# 发送Page改变事件,可以阻止
new_evt = PageChangingEvent(wxEVT_WIZARD_PAGE_CHANGING, self.GetId())
new_evt.SetPage(self.page_list[self.cur_page])
new_evt.SetDirection(False)
wx.PostEvent(self.parent, new_evt)
# 优先处理其他事件
wx.GetApp().Yield()
# 如果调用Veto方法,则事件被否决,直接退出函数
if G_VETO:
new_evt.Allow()
return
self._mainSizer.Detach(self.page_list[self.cur_page])
self.page_list[self.cur_page].Hide()
self.cur_page-=1
# 发送Page改变事件
new_evt = PageChangeEvent(wxEVT_WIZARD_PAGE_CHANGED, self.GetId())
new_evt.SetPage(self.page_list[self.cur_page])
wx.PostEvent(self.parent, new_evt)
self._mainSizer.Prepend(self.page_list[self.cur_page], 1, wx.EXPAND | wx.ALL, 10)
self.page_list[self.cur_page].Show()
self._mainSizer.Layout()
self.page_list[self.cur_page].Refresh()
if not self._IsLastPage(self.cur_page):
self._nextBtn.SetLabel(_(u"下一步>"))
if self._IsFirstPage(self.cur_page):
self._prevBtn.Enable(False)
def _IsFirstPage(self, page):
"""
判断是否是首页
"""
if page == self.page_list.index(self.page_list[0]):
return True
return False
def _IsLastPage(self, page):
"""
判断是否最后一页
"""
if page == self.page_list.index(self.page_list[-1]):
return True
return False
def _OnNext(self, event):
"""
下一页事件和完成事件
"""
global G_VETO
if self._nextBtn.GetLabel() == _(u"完成"):
# 发送Wizard完成事件
new_evt = WizardFinishedEvent(wxEVT_WIZARD_FINISHED, self.GetId())
wx.PostEvent(self.parent, new_evt)
return
# 发送Page改变事件,可以阻止
new_evt = PageChangingEvent(wxEVT_WIZARD_PAGE_CHANGING, self.GetId())
new_evt.SetPage(self.page_list[self.cur_page])
new_evt.SetDirection(True)
wx.PostEvent(self.parent, new_evt)
# 优先处理其他事件
wx.GetApp().Yield()
# 如果调用Veto方法,则事件被否决,直接退出函数
if G_VETO:
new_evt.Allow()
return
self._mainSizer.Detach(self.page_list[self.cur_page])
self.page_list[self.cur_page].Hide()
self.cur_page+=1
# 发送Page改变事件
new_evt = PageChangeEvent(wxEVT_WIZARD_PAGE_CHANGED, self.GetId())
new_evt.SetPage(self.page_list[self.cur_page])
wx.PostEvent(self.parent, new_evt)
self._mainSizer.Prepend(self.page_list[self.cur_page], 1, wx.EXPAND | wx.ALL, 10)
self.page_list[self.cur_page].Show()
self._mainSizer.Layout()
# 一定要放在布局计算完成后刷新,否在会存在刷新问题
self.page_list[self.cur_page].Refresh()
if self._IsLastPage(self.cur_page):
self._nextBtn.SetLabel(_(u"完成"))
if not self._IsFirstPage(self.cur_page):
self._prevBtn.Enable(True)
def _OnExit(self, event):
"""
取消事件
"""
# 发送Wizard取消事件
new_evt = WizardCancelEvent(wxEVT_WIZARD_CANCEL, self.GetId())
wx.PostEvent(self.parent, new_evt)
# 销毁
self.Destroy()
def AppendPage(self, page):
"""
添加向导页
"""
page.Hide()
self.page_list.append(page)
def AppendPages(self, *args):
"""
添加多个向导页
"""
for page in args:
page.Hide()
self.page_list.append(page)
def RunWizard(self, page):
"""
设置开始页,并显示向导框
"""
page.Show()
self._mainSizer.Prepend(page, 1, wx.EXPAND | wx.ALL, 10)
self.cur_page = self.page_list.index(page)
# 发送Page改变事件
new_evt = PageChangeEvent(wxEVT_WIZARD_PAGE_CHANGED, self.GetId())
new_evt.SetPage(self.page_list[self.cur_page])
wx.PostEvent(self.parent, new_evt)
if self._IsFirstPage(self.cur_page):
self._prevBtn.Enable(False)
self.ShowModal()
class WizardPageSimple(wx.Panel):
"""
向导页
"""
def __init__(self, parent):
super(WizardPageSimple, self).__init__(parent)