3

我正在制作一个非常适合向导概念的程序;用户将逐步完成为游戏创建角色的步骤。

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

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

但是,我在 wxPython 中找不到任何关于如何动态更改面板的文档。到目前为止,我发现的所有东西都非常静态,因此使用了向导。甚至“wxPython in Action”一书也没有提到它。

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

4

5 回答 5

5

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

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()
于 2008-10-22T08:04:52.057 回答
1

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

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

于 2008-10-29T16:09:32.753 回答
0

您可以尝试使用像WFTK这样的工作流引擎。在这种特殊情况下,作者使用 WFTK 对基于 wx 的应用程序进行了一些工作,并且可能会指导您查看示例。

于 2008-10-22T12:06:03.987 回答
0

我会彻底摆脱巫师。它们是我用过的最不愉快的东西。

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

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

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

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

于 2008-10-29T17:14:33.433 回答
0

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

如果某些用户可能经常执行该任务,您希望为这些高级用户提供一个轻量级的界面来执行相同的操作——即使它不那么自我解释。

请参阅:Windows Vista 用户体验指南 - 最常见的违规行为

奇才

首先考虑轻量级替代方案,例如对话框、任务窗格或单页。向导是一个沉重的 UI,最适合用于多步骤、不经常执行的任务。您不必使用向导——您可以在任何 UI 中提供有用的信息和帮助。

于 2008-10-29T17:38:48.610 回答