I have a wizard created using PyWizardPage. It starts with a main page, and then the user is brought through two more pages asking him for input information. One one of these pages, I've created two Browse buttons which ask the user to select two files. Now, on this page, I want the Next button to be disabled until the user selects the files.
I have scoured this site and Google for answers and have read things like this and this but can't seem to get my setup to work.
How do I disable just one button until the two Browse buttons are filled in?
As for my setup, I have a WizardPage class that I call to create each page in my wizard.
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
Then, in a separate file, I have a function to create each page. The function for the first page calls the functions to create the other pages. I also use helper functions called "browse1" and "browse2" to open a wx.FileDialog and such.
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
And the main code in pages.py is:
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)
Now, it is under the create_page2 function of pages.py that I want to put the code to disable the Next button until the two Browse buttons are filled in.
Doing this disables all Next buttons in the wizard:
wizard.FindWizardById(wx.ID_FORWARD).Disable()
Doing this also disables all Next buttons in the wizard:
for o in wizard.GetChildren():
if 'Button' in str(type(o)) and o.GetLabel() == "&Next >" and x1.GetValue() == "" and x2.GetValue() == "":
o.Disable()
Any help would be greatly appreciated.
EDIT:
Okay, so I tinkered with this a bit more and my code looks similar to Mike Driscoll's answer below. Here is my setup. I have three classes: WizardPage which creates a regular page, MyWizard which creates the first page and calls helper functions to create and link all the subsequent pages, and WizardPageDisabled which is the same as WizardPage but has the timer that you introduced with the ability to disable the Next button. I added this last class because this functionality may be needed for pages that's not just the first page of the wizard.
Now, I've come to a part when I see a problem. WizardPage uses the PyWizardPage constructor and MyWizard uses the wx.Wizard constructor. If I create WizardPageDisabled using the PyWizardPage constructor, the line forwardBtn.Disable() returns the NoneType has no attribute Disable error. If I use the wx.Wizard constructor, the page doesn't show up at all.
So in addition to my issue above, I guess another clarification question is: what is the difference between PyWizardPage and wx.Wizard?
page1.GetNext().Disable()? - Joran Beasleypage1.GetNext().FindWindowById(wx.ID_FORWARD).Disable()and was told thatNoneType object has no attribute Disable- noblerare