質問
私は、ウィザードの概念に理想的に適合するプログラムを作成しています。ユーザーはゲームのキャラクターを作成するための手順を順を追って説明されています。
ただし、ウィザードの制限により、「エレガント」なデザインが難しくなっていることがわかりました。論理フロー。たとえば、ウィザードのすべてのページが同時に初期化されるため、あるページに入力した値を次のページで使用することはできません。フィールドを自動入力するだけでなく、前のページから値を取得するには、各ページにボタンを配置する必要があります。
ウィザードを使用する代わりの方法を考えました。最良のアイデアは、あるパネルにいくつかのボタンを付けて、別のパネルの情報を変更することです分割ウィンドウ。
ただし、wxPythonには、パネルを動的に変更する方法に関するドキュメントがありません。私がこれまでに見つけたものはすべて非常に静的なので、ウィザードを使用します。 「wxPython in Action」でさえも本はそれについて言及していません。
「動的パネル」を作成するためのチュートリアルはありますか?ウィザードのより良い管理?
解決
これは簡単な例です。このようにして、「ウィザード」を作成できます。状態がオンデマンドで初期化される異なるページである有限状態マシンのように動作します。また、データはページ間で共有されます。
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()
他のヒント
wxPythonデモには、「動的」の例があります。ウィザード。ページはGetNext()およびGetPrev()をオーバーライドして、ページを動的に表示します。これは基本的な手法を示しています。ページを追加および削除したり、その場でページを変更したり、ページを動的に並べ替えたりするために拡張できます。
ただし、ウィザードクラスは便利です。変更するか、独自の実装を作成できます。最近人気のあるスタイルは、HTMLベースのプレゼンテーションを使用することです。 wxHtmlコントロール、またはアプリがWindowsのみの場合はIEHtmlWindowコントロールでこれをエミュレートできます。
WFTK のようなワークフローエンジンを使用してみてください。この特定のケースでは、作者はWFTKを使用してwxベースのアプリでいくつかの作業を行っており、おそらく例を紹介できます。
ウィザード全体を削除します。それらは私が今まで使った中で最も不快なものです。
「次へ」をクリックするウィザードアプリケーションを必要とする問題は、おそらくより良いユーザーインターフェイスを少し異なる方法で適用できる問題です。迷惑な「次へ」ボタンでダイアログを表示する代わりに。これを行います:
ページを作成します。ユーザーが情報をページに挿入したら、入力に応じて情報を拡張または短縮します。アプリケーションで処理を続行する必要があり、その後復帰できない場合は、新しいページを書き込むか、現在のページの以前のセクションを無効にします。ユーザーからの入力が不要になった場合、またはアプリが終了したら、ボタンを表示したり、既存のボタンを有効にしたりできます。
すべてをブラウザに実装する必要があるわけではありません。ボタンとラベルをフラットリストに含めることができる単純なスクロールコンテナを作成します。
利点:ユーザーはタブをクリックするだけで、すべての処理をページ入力の最後に置くことが推奨されます。
ウィザードは、多段階で頻繁に実行されないタスクのインターフェースであることに注意してください。ウィザードは、ユーザーが実際に理解していないことをガイドするために使用されます。ほとんど理解できないためです。
また、一部のユーザーが頻繁にタスクを実行する場合は、自明ではないにしても、同じことを行うための軽量インターフェースをそれらのパワーユーザーに提供する必要があります。
参照: Windows Vistaユーザーエクスペリエンスガイドライン-違反のトップ
ウィザード
ダイアログボックス、タスクなどの軽量の代替案を最初に検討する ペイン、または単一ページ。ウィザードは マルチステップに最適な重いUI 頻繁に実行されないタスク。あなたはしません ウィザードを使用する必要があります—提供できます 役立つ情報と支援 任意のUI。