自己动手实现wxpython向导框

<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)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值