Python 向导的替代方案

Python 向导的替代方案,python,wxpython,wizard,Python,Wxpython,Wizard,我正在制作一个符合精灵概念的程序;引导用户完成为游戏创建角色的步骤 然而,我意识到向导的局限性使得设计“优雅”的逻辑流变得困难。例如,由于向导的所有页面都是同时初始化的,因此我无法将一个页面中输入的值用于下一个页面。我必须在每个页面上放置一个按钮,以从上一页获取值,而不是简单地自动填充字段 我已经考虑过使用向导的替代方案。我认为最好的办法是在一个面板上有一些按钮来更改另一个面板上的信息,例如拆分窗口 但是,我在wxPython中找不到任何关于如何动态更改面板的文档。到目前为止,我发现的一切都是非

我正在制作一个符合精灵概念的程序;引导用户完成为游戏创建角色的步骤

然而,我意识到向导的局限性使得设计“优雅”的逻辑流变得困难。例如,由于向导的所有页面都是同时初始化的,因此我无法将一个页面中输入的值用于下一个页面。我必须在每个页面上放置一个按钮,以从上一页获取值,而不是简单地自动填充字段

我已经考虑过使用向导的替代方案。我认为最好的办法是在一个面板上有一些按钮来更改另一个面板上的信息,例如拆分窗口

但是,我在wxPython中找不到任何关于如何动态更改面板的文档。到目前为止,我发现的一切都是非常静态的,因此使用了向导。即使是《wxPython在行动》一书也没有提到这一点


是否有制作“动态面板”或更好地管理向导的教程?

这里是一个简单的示例。通过这种方式,您可以使“向导”像有限状态机一样工作,其中状态是按需初始化的不同页面。此外,数据在页面之间共享

import wx
import wx.lib.newevent


(PageChangeEvent, EVT_PAGE_CHANGE) = wx.lib.newevent.NewEvent()


class Data:
    foo = None
    bar = None


class Page1(wx.Panel):
    def __init__(self, parent, data):
        wx.Panel.__init__(self, parent)
        self.parent = parent
        self.data = data

        sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(sizer)
        label = wx.StaticText(self, label="Page 1 - foo")
        self.foo = wx.TextCtrl(self)
        goto_page2 = wx.Button(self, label="Go to page 2")

        for c in (label, self.foo, goto_page2):
            sizer.Add(c, 0, wx.TOP, 5)

        goto_page2.Bind(wx.EVT_BUTTON, self.OnPage2)

    def OnPage2(self, event):
        self.data.foo = self.foo.Value
        wx.PostEvent(self.parent, PageChangeEvent(page=Page2))


class Page2(wx.Panel):
    def __init__(self, parent, data):
        wx.Panel.__init__(self, parent)
        self.parent = parent
        self.data = data

        sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(sizer)
        label = wx.StaticText(self, label="Page 2 - bar")
        self.bar = wx.TextCtrl(self)
        goto_finish = wx.Button(self, label="Finish")

        for c in (label, self.bar, goto_finish):
            sizer.Add(c, 0, wx.TOP, 5)

        goto_finish.Bind(wx.EVT_BUTTON, self.OnFinish)

    def OnFinish(self, event):
        self.data.bar = self.bar.Value
        wx.PostEvent(self.parent, PageChangeEvent(page=finish))


def finish(parent, data):
    wx.MessageBox("foo = %s\nbar = %s" % (data.foo, data.bar))
    wx.GetApp().ExitMainLoop()


class Test(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None)
        self.data = Data()
        self.current_page = None

        self.Bind(EVT_PAGE_CHANGE, self.OnPageChange)
        wx.PostEvent(self, PageChangeEvent(page=Page1))

    def OnPageChange(self, event):
        page = event.page(self, self.data)
        if page == None:
            return
        if self.current_page:
            self.current_page.Destroy()
        self.current_page = page
        page.Layout()
        page.Fit()
        page.Refresh()


app = wx.PySimpleApp()
app.TopWindow = Test()
app.TopWindow.Show()
app.MainLoop()

您可以尝试使用类似的工作流引擎。在本例中,作者使用WFTK对基于wx的应用程序做了一些工作,并可能指导您使用示例。

wxPython演示有一个“动态”向导示例。页面覆盖GetNext()和GetPrev()以动态显示页面。这显示了基本技术;您可以扩展它来添加和删除页面、动态更改页面以及动态重新排列页面


不过,向导类只是一种方便。您可以修改它,或者创建自己的实现。现在流行的一种风格是使用基于HTML的表示;您可以使用wxHtml控件或IEHtmlWindow控件(如果您的应用程序仅限于Windows)来模拟这一点。

我将完全摆脱向导。它们是我用过的最不愉快的东西

需要在向导应用程序中单击“下一步”的问题可能是您可以以稍微不同的方式应用更好的用户界面的问题。而不是用恼人的“下一步”按钮弹出对话框。这样做:

打开一页。当用户将信息插入页面时,根据输入扩展或缩短信息。如果您的应用程序需要进行一些处理才能继续,并且之后无法恢复,请编写一个新页面或禁用当前页面的早期部分。当您不再需要用户的任何输入或应用程序完成时,您可以显示一个按钮或启用现有的此类应用程序

我并不是说你们应该在浏览器中实现这一切。制作一个简单的滚动容器,可以在平面列表中包含按钮和标签


好处:用户只需单击一个选项卡,我们鼓励您将所有处理放在填充页面的末尾。

需要注意的是,向导应该是多步骤、不经常执行的任务的界面。该向导用于指导用户完成一些他们并不真正理解的事情,因为他们几乎从不这样做

如果一些用户可能经常执行此任务,那么您希望为这些超级用户提供一个轻量级的界面来执行相同的任务,即使它不那么自圆其说

请参阅:

向导

首先考虑轻量级替代方案,如对话框、任务 窗格或单页。向导是 一个沉重的用户界面,最好用于多步骤, 不经常执行的任务。你不知道 必须使用您可以提供的向导 在以下方面提供有用的信息和协助: 任何用户界面