2014-02-13 40 views
0

我有一個使用PyWizardPage創建的嚮導。它從一個主頁面開始,然後用戶再通過兩個頁面向他詢問輸入信息。其中一個頁面,我創建了兩個瀏覽按鈕,要求用戶選擇兩個文件。現在,在此頁面上,我希望禁用「下一步」按鈕,直到用戶選擇文件。如何禁用wxPython嚮導頁面的「下一步」按鈕?

我已經搜遍這個網站和谷歌的答案,並已閱讀的東西,如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) 

現在,它是pages.pycreate_page2功能,我希望把下代碼禁用Next按鈕,直到這兩個瀏覽按鈕被填充。

這樣做禁用嚮導中的所有Next按鈕:

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

這樣做也會禁用嚮導中的所有Next按鈕:

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

任何幫助將不勝感激。

編輯:

好了,所以我修修補補這個多一點,我的代碼類似於下面邁克Driscoll的答案。這是我的設置。我有三個類:WizardPage創建一個常規頁面,MyWizard它創建第一頁並調用輔助函數來創建並鏈接所有後續頁面,WizardPageDisabledWizardPage相同,但具有您引入的計時器禁用下一步按鈕。我添加了最後一個類,因爲這個功能可能需要用於不僅僅是嚮導第一頁的頁面。

現在,當我看到問題時,我已經到了一個地步。 WizardPage使用PyWizardPage構造函數,MyWizard使用wx.Wizard構造函數。如果我使用PyWizardPage構造函數創建WizardPageDisabled,那麼行forwardBtn.Disable()將返回NoneType has no attribute Disable錯誤。如果我使用wx.Wizard構造函數,則頁面根本不顯示。

所以除了我上面的問題,我想另外一個澄清的問題是:PyWizardPagewx.Wizard之間有什麼區別?

+0

你試過'page1.GetNext()禁用()'? –

+0

@Joran Beasley:不,我沒有。剛剛嘗試過,它會禁用整個頁面,而不僅僅是下一步按鈕。然後我嘗試了'page1.GetNext()。FindWindowById(wx.ID_FORWARD).Disable()'並被告知'NoneType對象沒有禁用屬性' – noblerare

+0

:/抱歉我不使用具有該模塊的wx版本... –

回答

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() 
+0

感謝您的回答。我理解你的概念,並且我運行了你的代碼,但是我似乎無法使其適用於我的案例。就我而言,有問題的頁面恰好是我希望禁用「下一步」按鈕的第三個頁面。另外,與'FindWindowById'有關的兩行似乎適用於你的代碼,但是當我在我的類的'init'函數中添加這些行時,我總是在'NoneType沒有屬性Disable'時出錯,這非常令人沮喪。 – noblerare

+0

確保使用Wizard類的實例調用FindWindowById。同樣對於第三頁,我懷疑你只會在第三頁到達時才運行這個調用。因此綁定到更改的頁面事件並在運行之前檢查您的頁面。 –

+0

感謝您的評論。我修改了一些代碼,使它看起來像你的結構,然後似乎遇到了我認爲可能是我的問題的癥結所在,所以我在我的問題底部將它編寫爲一個編輯。謝謝你的幫助! – noblerare

相關問題