如何禁用wxPython向导页面的“下一步”按钮?

时间:2014-02-13 19:17:02

标签: python wxpython wizard

我有一个使用PyWizardPage创建的向导。它从一个主页面开始,然后用户再通过两个页面询问他输入信息。其中一个页面,我创建了两个浏览按钮,要求用户选择两个文件。现在,在此页面上,我希望在用户选择文件之前禁用“下一步”按钮。

我已经搜索了这个网站和谷歌的答案,并阅读了thisthis之类的内容,但似乎无法让我的设置正常运行。

如何在中填充两个“浏览”按钮之前,只禁用一个按钮

至于我的设置,我有一个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 * 

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)) 
    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)) 
    x2 = wx.TextCtrl(...) # the text area where the Browse path is populated


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

    return page2

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)

现在,它位于create_page2 pages.py函数之下,我希望将代码设置为禁用“下一步”按钮,直到填写两个“浏览”按钮。< / p>

执行此操作将禁用向导中的所有“下一步”按钮:

wizard.FindWizardById(wx.ID_FORWARD).Disable()

执行此操作还会禁用向导中的所有“下一步”按钮:

for o in wizard.GetChildren():
    if 'Button' in str(type(o)) and o.GetLabel() == "&Next >" and x1.GetValue() == "" and x2.GetValue() == "":
    o.Disable()

非常感谢任何帮助。

编辑:

好的,所以我对此进行了更多修改,我的代码看起来与Mike Driscoll的答案类似。这是我的设置。我有三个类:WizardPage创建一个常规页面,MyWizard创建第一个页面并调用辅助函数来创建和链接所有后续页面,WizardPageDisabled与...相同WizardPage但你有一个计时器,你可以禁用Next按钮。我添加了最后一个类,因为对于不仅仅是向导的第一页的页面,可能需要此功能。

现在,当我发现问题时,我已经参与其中。 WizardPage使用PyWizardPage构造函数,MyWizard使用wx.Wizard构造函数。如果我使用WizardPageDisabled构造函数创建PyWizardPage,则行forwardBtn.Disable()会返回NoneType has no attribute Disable错误。如果我使用wx.Wizard构造函数,则该页面根本不会显示。

因此,除了上述问题之外,我想另一个澄清问题是:PyWizardPagewx.Wizard之间有什么区别?

1 个答案:

答案 0 :(得分:0)

这是一个鬼鬼祟祟的人。我确定有多种方法可以做到这一点,但我想出的方法是使用wx.Timer来检查文本控件是否有值。如果他们这样做,那么然后重新启用该按钮。顺便说一下,我给你的answer(你链接的)前一段时间禁用按钮确实有效。 Joran是对的......

无论如何,这是我的实施:

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")
        page3 = WizardPage(self, "Page 3")

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

        return page1

    #----------------------------------------------------------------------
    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()