实战wxPython:027 - 向导对话框Wizard

本文介绍了如何使用wxPython库创建和管理向导对话框,包括wx.adv.Wizard类及其页面wx.adv.WizardPage和wx.adv.WizardPageSimple的使用。向导对话框通过一系列页面引导用户逐步完成复杂操作,提供了如EVT_WIZARD_PAGE_CHANGED等事件以及允许Next/Back操作的方法。示例代码展示了如何构建和链接两个页面的向导,并强调了每个页面需实现AllowNext和AllowBack方法来控制导航。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

向导(Wizard,在macOS上也称为助手)是一种特殊的输入对话框,由一系列页面组成。向导的目的是引导用户逐步进行某个操作过程。 wx.adv.Wizard继承自wx.Dialog并表示一个向导,wx.adv.Wizard中的每一个页面都是有一个wx.adv.WizardPage(一个wx.Panel的类)。可以直接使用这些类来创建自己的向导,也可以将他们子类化以实现更多控制,来创建自己的更有特点的向导。

一、wx.adv.Wizard

wx.adv.Wizard提供一个”类似向导”的对话框。这些对话框对Windows用户来说非常熟悉,只不过是一系列的“页面”,每个页面都显示在一个对话框中,其中有按钮可以导航到下一个(和上一个)页面。这些向导通常用于将复杂的对话框分解为几个简单的步骤,主要对新手用户有用,因此保持它们尽可能简单是很重要的。

要显示向导对话框,必须首先使用非默认构造函数或默认构造函数创建wx.adv.Wizard类的实例。然后添加希望在向导里显示的所有页面,并调用wx.adv.Wizard.RunWizard。最后调用“wizard->Destroy()”,否则应用程序将挂起退出由于一个未销毁的窗口。

wx.adv.Wizard发出的事件:

  • EVT_WIZARD_PAGE_CHANGED:页面刚刚被更改(此事件不能被否决)。
  • EVT_WIZARD_PAGE_CHANGING:页面正在被更改(此事件可以被否决)。
  • EVT_WIZARD_BEFORE_PAGE_CHANGED:在单击Next之后但在调用GetNext之前调用。与EVT_WIZARD_CHANGING不同,此函数的处理程序可以更改可能影响GetNext返回值的状态(此事件可以被否决)。
  • EVT_WIZARD_PAGE_SHOWN:页面被显示和布局(此事件不能被否决)。
  • EVT_WIZARD_CANCEL:用户试图取消向导(此事件也可能被否决)。
  • EVT_WIZARD_HELP:按下向导帮助按钮。
  • EVT_WIZARD_FINISHED:按下向导完成按钮。

wx.adv.Wizard常用方法:

  • GetBitmap(self):返回向导使用的位图。
  • GetBitmapBackgroundColour(self):如果设置了非零位图位置标志,则返回应用于填充向导或页面位图未占用区域的颜色。
  • GetBitmapPlacement(self):返回指示向导或页面位图应如何展开和定位以适应页面高度的标志。默认情况下为0(不进行扩展)。
  • GetCurrentPage(self):在向导运行时获取当前页面。如果现在没有执行RunWizard,则返回None。
  • GetMinimumBitmapWidth(self):如果设置了非零位图位置标志,则返回包含实际向导或页位图的位图最小宽度。
  • GetPageAreaSizer(self):返回指向页面区域大小的指针。向导使用大小调整器进行布局,页面区域大小调整器是页面的占位符。所有页面在显示之前都会调整大小以匹配向导页面区域。
  • GetPageSize(self):返回可用于页面的大小。
  • HasNextPage(selfpage):如果此页不是向导中的最后一页,则返回True。
  • HasPrevPage(selfpage):如果此页面不是向导中的第一个页面,则返回True。
  • IsRunning(self):向导页面正在运行中。
  • RunWizard(selffirstPage):从给定的页面开始执行向导,如果向导成功完成则返回True,如果用户取消则返回False。firstPage不能为None。
  • SetBitmap(selfbitmap):设置向导使用的位图。
  • SetBitmapBackgroundColour(selfcolour):如果设置了非零位图位置标志,则设置应用于填充向导或页位图未占用的区域的颜色。
  • SetBitmapPlacement(selfplacement):设置指示向导或页面位图应如何展开和定位以适应页面高度的标志。默认情况下,placement为0(不进行扩展)。Placement是一个位列表,包含以下可能的值:

wx.adv.WIZARD_VALIGN_TOP:在顶部对齐位图。
wx.adv.WIZARD_VALIGN_CENTRE:将位图垂直居中。
wx.adv.WIZARD_VALIGN_BOTTOM:在底部对齐位图。

wx.adv.WIZARD_HALIGN_LEFT:左对齐位图。
wx.adv.WIZARD_HALIGN_CENTRE:将位图水平居中。
wx.adv.WIZARD_HALIGN_RIGHT:右对齐位图。

wx.adv.WIZARD_TILE:位图将平铺以适应可用空间。

  • SetBorder(selfborder):设置页面区域周围边框的宽度。默认值为0(为了向后兼容,如果在GetPageAreaSizer中没有页面,默认值是5像素)。如果页面中的所有控件周围都有5点边框,并且页面区域周围的边框保留为零,则将在控件边框上沿所有对话框边框添加5点空白,以便将页面控件与对话框边框和非页面控件之间的距离拉大10点。
  • SetMinimumBitmapWidth(selfwidth):如果设置了非零位图位置标志,则设置将构造为包含实际向导或页位图的位图的最小宽度。如果在使用位图放置(placement)时没有设置,初始布局可能不正确。
  • SetPageSize(selfsizePage):设置向导页可用的最小尺寸。向导将考虑位图(如果有的话)本身的大小。另外,向导永远不会小于默认尺寸。使用此函数的推荐方法是使用尺寸调整器来布局所有向导页面(即使向导不能调整尺寸),然后在循环中使用wx.size.calcmin来计算页面的最大和最小尺寸,并将其传递给SetPageSize。
  • ShowPage(selfpagegoingForward):显示给定的向导页面。首先调用当前页面上的TransferDataFromWindow。如果页面未作改变则返回False。

 图1. wx.adv.Wizard类继承关系

二、wx.adv.WizardPag

wx.adv.WizardPage是wx.adv.Wizard中的一个页面,它必须知道前一个页面和后一个页面是什么(对于第一页/最后一页可能是None)。wx.adv.WizardPage只是一个面板(Panel),因此控件可以以常规的方式直接放在它上面。

为了提供最大的灵活性,wx.adv.WizardPage允许程序动态地(在运行时)决定向导中页面的顺序。通常情况下,页面的顺序是预先知道的,在这种情况下,wx.adv.WizardPageSimple类就足够了,而且使用起来也更简单。

wx.adv.WizardPage的常用方法有:

  • GetBitmap(self):该方法由wx.adv.Wizard调用,以获得与页面一起显示的位图。默认情况下,在wx.adv.WizardPage构造函数中设置的m_bitmap成员变量。如果位图没有显式地设置(例如,如果返回wx.NullBitmap),则应该使用向导的默认位图。
  • GetNext(self):获取当用户选择“下一个(Next)”按钮时应该显示的页面。如果返回None,则该按钮将被禁用。
  • GetPrev(self):获取当用户选择“返回(Back)”按钮时应该显示的页面:如果返回None,则该按钮将被禁用。

三、wx.adv.WizardPageSimple

wx.adv.WizardPageSimple是最简单的wx.adv.WizardPage实现。

wx.adv.WizardPageSimpl的常用方法有:

  • SetNext(selfnext):设置下一个页面。
  • SetPrev(selfprev):设置前一个页面。

 图2. Wx.adv.WizardPageSimple类继承关系

四、wx.adv.Wizard演示

下面的代码演示了如何在程序中创建一个向导功能。

#向导(wx.adv.Wizard)

import wx, wx.adv

class configWizard(wx.adv.Wizard):
    def __init__(self):
        super(configWizard, self).__init__(None, wx.ID_ANY, "配置向导")

        self.Bind(wx.adv.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged)
        self.Bind(wx.adv.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging)

        self.firstInfoPage = Info1Page(self, "标题1")
        self.machineSelectPage = Info2Page(self, "标题2")

        #将页面添加到向导列表链中
        wx.adv.WizardPageSimple.Chain(self.firstInfoPage, self.machineSelectPage)

        # self.GetPageAreaSizer().Add(self.firstInfoPage)
        self.RunWizard(self.firstInfoPage)
        self.Destroy()

    def OnPageChanging(self, e):
        print(e.GetPage())

    #页面发生改变后执行的动作
    def OnPageChanged(self, e):
        #后一个页面
        if e.GetPage().AllowNext():
            self.FindWindowById(wx.ID_FORWARD).Enable()
        else:
            self.FindWindowById(wx.ID_FORWARD).Disable()

        #前一个页面
        if e.GetPage().AllowBack():
            self.FindWindowById(wx.ID_BACKWARD).Enable()
        else:
            self.FindWindowById(wx.ID_BACKWARD).Disable()

class Info1Page(wx.adv.WizardPageSimple):
    def __init__(self, parent, title):
        wx.adv.WizardPageSimple.__init__(self, parent)

        sizer = wx.GridBagSizer(5, 5)
        self.sizer = sizer
        self.SetSizer(sizer)

        st_title = wx.StaticText(self, wx.ID_ANY, title)
        st_title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))
        sizer.Add(st_title, pos = (0, 0), span = (1, 2), flag = wx.ALIGN_CENTER | wx.ALL)
        sizer.Add(wx.StaticLine(self, -1), pos = (1, 0), span = (1, 2), flag = wx.EXPAND | wx.ALL)
        sizer.AddGrowableCol(1)

        def AllowNext(self):
            print("page 1")
            return True

        def AllowBack(self):
            print("page 2")
            return False

class Info2Page(wx.adv.WizardPageSimple):
    def __init__(self, parent, title):
        wx.adv.WizardPageSimple.__init__(self, parent)

        sizer = wx.GridBagSizer(5, 5)
        self.sizer = sizer
        self.SetSizer(sizer)

        st_title = wx.StaticText(self, wx.ID_ANY, title)
        st_title.SetFont(wx.Font(18, wx.SWISS, wx.NORMAL, wx.BOLD))
        sizer.Add(st_title, pos=(0,0), span = (1, 2), flag = wx.ALIGN_CENTER | wx.ALL)
        sizer.Add(wx.StaticLine(self, -1), pos = (1, 0), span = (1, 2), flag = wx.EXPAND | wx.ALL)
        sizer.AddGrowableCol(1)

    def AllowNext(self):
        print("page 1")
        return True

    def AllowBack(self):
        print("page 2")
        return True

class SampleWizard(wx.Frame):

    def __init__(self, *args, **kw):
        super(SampleWizard, self).__init__(*args, **kw)

        self.InitUi()

    def InitUi(self):
        #设置标题
        self.SetTitle("实战wxPython: Wizard演示")
        #设置窗口尺寸
        self.SetSize(400, 240)
        
        panel = wx.Panel(self)
        btnStart = wx.Button(panel, label="开始")
        self.Bind(wx.EVT_BUTTON, self.OnStart, btnStart)

        self.Centre()

    def OnStart(self, e):
        #运行向导配置
        configWizard()

def main():
    app = wx.App()
    sample = SampleWizard(None)
    sample.Show()
    app.MainLoop()

if __name__ == "__main__":
    main()

运行上述代码,弹出主界面窗口,点击”开始”按钮,将运行一个向导演示,这个向导演示包括两个页面,分别演示了向导的第一个页面和最后一个页面。

 图3. 向导设置的第一个页面

 图4. 向导设置的最后一个页面

特别说明:

  1. 每一个向导page类都要继承wx.adv.WizardPageSimple,其中有两个函数必须实现:
  • AllowNext。
  • AllowBack。

2. 使用
wx.adv.WizardPageSimple.Chain()可以将两个向导page前后关联起来,如果有多个page,同样如此。

五、本文知识点

  • 了解向导对话框wx.Wizard和向导页面wx.WizardPage。
  • 如何在应用中构建一个向导设置。

前一篇:实战wxPython:026 - 进度对话框ProgressDialog

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值