如何在wxPython PyWizardPage向导的页面之间传递信息?

时间:2014-02-13 21:51:46

标签: python wxpython wizard

我有一个使用PyWizardPage创建的向导。它从一个主页开始,然后用户被带来几个页面,询问他输入信息。在其中一个页面上,我创建了一个“浏览”按钮,要求用户选择一个文件。然后,在下一页上,我有一个“验证详细信息”的东西,它显示一个框,其中包含用户通过向导选择的所有输入,并要求他在继续之前确保信息正确。

我的问题是,我无法将之前页面上的任何用户输入传递到我的“验证详细信息”页面。

对于我的设置,我有一个WizardPage类,我调用它来创建向导中的每个页面。

mywizard.py

import wx
import wx.wizard

class WizardPage(wx.wizard.PyWizardPage):
    def __init__(self, parent, title):
        wx.wizard.PyWizardPage.__init__(self, parent)
        self.next = None
        self.prev = None
        self.initializeUI(title)

    def initializeUI(self, title):      
        # create grid layout manager    
        self.sizer = wx.GridBagSizer()
        self.SetSizerAndFit(self.sizer)

    def addWidget(self, widget, pos, span): 
        self.sizer.Add(widget, pos, span, wx.EXPAND)

    # getters and setters 
    def SetPrev(self, prev):
        self.prev = prev

    def SetNext(self, next):
        self.next = next

    def GetPrev(self):
        return self.prev

    def GetNext(self):
        return self.next

然后,在一个单独的文件中,我有一个创建每个页面的功能。第一页的功能调用函数来创建其他页面。我还使用名为“browse1”和“browse2”的辅助函数来打开wx.FileDialog等。

pages.py

import wx
from mywizard import * 

#### HELPER FUNCTIONS ####
def browse1(event, parent_page):
    wildcards = ...
    dlg = wx.FileDialog(parent_page, "Blahblah", "", "",
                            wildcards, wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)

    if dlg.ShowModal() == wx.ID_OK:
        global x1
        global bro1
        x1.SetValue(dlg.GetDirectory() + "\\" + dlg.GetFilename())
        bro1 = x1.GetValue()

def browse2(event, parent_page):
    wildcards = ...
    dlg = wx.FileDialog(parent_page, "Select new certificate", "", "",
                            wildcards, wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)

    if dlg.ShowModal() == wx.ID_OK:
        global x2
        global bro2
        x2.SetValue(dlg.GetDirectory() + "\\" + dlg.GetFilename())
        bro2 = x2.GetValue()

#### END HELPER FUNCTIONS ####

def create_page1(wizard):
    page1 = WizardPage(wizard, "Page 1")
    d = wx.StaticText(...)
    page1.addWidget(d, (2, 1), (1,5))

    page2 = create_update_certs_page2(wizard)
    page3 = create_update_certs_page3(wizard)

    # Set links
    page2.SetPrev(page1)
    page1.SetNext(page2)
    page3.SetPrev(page2)
    page2.SetNext(page3)

    return page1

def create_page2(wizard):
    page2 = WizardPage(wizard, "Page 2")

    b1 = wx.Button(page2, -1, "Browse...", wx.DefaultPosition, (85, 23))
    b1.Bind(wx.EVT_BUTTON, lambda evt: browse1(evt, page2)) 

    global x1
    x1 = wx.TextCtrl(...) # the text area where the Browse path is populated

    b2 = wx.Button(page2, -1, "Browse...", wx.DefaultPosition, (85, 23))
    b2.Bind(wx.EVT_BUTTON, lambda evt: browse2(evt, page2)) 

    global x2
    x2 = wx.TextCtrl(...) # the text area where the Browse path is populated

    page2.addWidget(b1, ..., ...)
    page2.addWidget(b2, ..., ...)
    page2.addWidget(x1, ..., ...)
    page2.addWidget(x2, ..., ...)

    return page2

def create_page3(wizard):
    print "bro1 is" + bro1 # these print empty strings
    print "bro2 is" + bro2 # not, the browse path and file that should be populated

基本上,x1x2引用了我创建全局的wx.TextCtrl小部件,因此我可以在browse1browse2函数中填充它们。现在,我想在bro1函数中的bro2create_page3变量中访问其填充值,但不显示任何内容。

pages.py 中的主要代码是:

app = wx.App(redirect = False)
wizard = wx.wizard.Wizard(None, -1, "Some Title")
wizard.SetPageSize((500, 350))

mypage1 = create_page1(wizard)

# Let's go!
wizard.RunWizard(mypage1)

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

你可以传递msvalkon提到的值。但是我认为子类化wx.wizard.Wizard会更简单。然后,您可以在类中创建各种小部件,并将其父级创建到不同的页面。这使您可以轻松地跨页面访问变量。这是我给你的last question答案的扩展:

import wx
import wx.wizard

class WizardPage(wx.wizard.PyWizardPage):
    def __init__(self, parent, title):
        wx.wizard.PyWizardPage.__init__(self, parent)
        self.next = None
        self.prev = None
        self.initializeUI(title)

    def initializeUI(self, title):      
        # create grid layout manager    
        self.sizer = wx.GridBagSizer()
        self.SetSizerAndFit(self.sizer)

    def addWidget(self, widget, pos, span): 
        self.sizer.Add(widget, pos, span, wx.EXPAND)

    # getters and setters 
    def SetPrev(self, prev):
        self.prev = prev

    def SetNext(self, next):
        self.next = next

    def GetPrev(self):
        return self.prev

    def GetNext(self):
        return self.next

########################################################################
class MyWizard(wx.wizard.Wizard):
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.wizard.Wizard.__init__(self, None, -1, "Some Title")
        self.SetPageSize((500, 350))

        mypage1 = self.create_page1()

        forward_btn = self.FindWindowById(wx.ID_FORWARD) 
        forward_btn.Disable()

        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.onUpdate, self.timer)
        self.timer.Start(1)

        self.RunWizard(mypage1)

    #----------------------------------------------------------------------
    def create_page1(self):
        page1 = WizardPage(self, "Page 1")
        d = wx.StaticText(page1, label="test")
        page1.addWidget(d, (2, 1), (1,5))

        self.text1 = wx.TextCtrl(page1)
        page1.addWidget(self.text1, (3,1), (1,5))

        self.text2 = wx.TextCtrl(page1)
        page1.addWidget(self.text2, (4,1), (1,5))

        page2 = WizardPage(self, "Page 2")
        page2.SetName("page2")
        self.text3 = wx.TextCtrl(page2)
        self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.onPageChanged)
        page3 = WizardPage(self, "Page 3")

        # Set links
        page2.SetPrev(page1)
        page1.SetNext(page2)
        page3.SetPrev(page2)
        page2.SetNext(page3)

        return page1

    #----------------------------------------------------------------------
    def onPageChanged(self, event):
        """"""
        page = event.GetPage()
        print
        if page.GetName() == "page2":
            self.text3.SetValue(self.text2.GetValue())

    #----------------------------------------------------------------------
    def onUpdate(self, event):
        """
        Enables the Next button if both text controls have values
        """
        value_one = self.text1.GetValue()
        value_two = self.text2.GetValue()
        if value_one and value_two:
            forward_btn = self.FindWindowById(wx.ID_FORWARD) 
            forward_btn.Enable()
            self.timer.Stop()

#----------------------------------------------------------------------
def main():
    """"""
    wizard = MyWizard()

#----------------------------------------------------------------------
if __name__ == "__main__":
    app = wx.App(False)
    main()
    app.MainLoop()

这里的想法是给每个页面一个唯一的名称,然后捕获EVT_WIZARD_PAGE_CHANGED。在处理程序中,您可以检查您所在的页面并相应地更新其内容。

答案 1 :(得分:1)

我不完全确定最常用的做法是什么,但这就是我之前处理过这个问题的方法。

wx.wizard.Wizard - 类进行子类化,并将wx事件wx.wizard.EVT_WIZARD_ON_PAGE_CHANGINGwx.wizard.EVT_WIZARD_ON_PAGE_CHANGED绑定到您的类的方法,以确保数据一致地来回传输。

wx.wizard.EVT_WIZARD_ON_PAGE_CHANGING时会触发next。处理此事件的方法负责保存当前页面数据。

当页面实际更改时,wx.wizard.EVT_WIZARD_ON_PAGE_CHANGED将触发。处理此事件的方法负责将数据从上一页填充到当前页面字段,或者执行您想要对其执行的任何操作。