2014-02-13 2 views
0

나는 PyWizardPage를 사용하여 만든 마법사가 있습니다. 그것은 메인 페이지로 시작하고, 사용자는 입력 정보를 요구하는 두 페이지를 더 가져다줍니다. 이 페이지 중 하나는 사용자에게 두 개의 파일을 선택하도록 요청하는 두 개의 찾아보기 버튼을 만들었습니다. 이제이 페이지에서 사용자가 파일을 선택할 때까지 [다음] 단추를 사용할 수 없도록 설정합니다.어떻게 wxPython 마법사 페이지의 "다음"버튼을 비활성화합니까?

이 사이트와 Google에서 답변을 구하고 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 기능 받고있다 다음 단추를 사용하지 않으려면 두 개의 찾아보기 단추가 채워지는 코드를 입력하십시오.

이 마법사의 모든 다음 버튼을 비활성화 하 :

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

어떤 도움을 주시면 감사하겠습니다.

는 편집 :

좋아, 그래서 좀 더이 함께 만지작 내 코드는 다음과 마이크 드리스콜의 대답은 비슷합니다. 여기에 내 설정입니다. 세 개의 클래스가 있습니다 : WizardPage 일반 페이지를 만들고, 첫 번째 페이지를 만들고과 동일한 WizardPageDisabled을 만들고 연결하는 도우미 함수를 호출하는 MyWizard입니다.하지만 소개 한 타이머가 있습니다. 다음 버튼을 비활성화하십시오. 이 마지막 클래스를 추가 한 이유는이 기능이 마법사의 첫 페이지가 아닌 페이지에 필요할 수 있기 때문입니다.

이제는 문제가 생겼을 때 일부러 왔습니다. WizardPagePyWizardPage 생성자를 사용하고 MyWizardwx.Wizard 생성자를 사용합니다.PyWizardPage 생성자를 사용하여 WizardPageDisabled을 만들면 forwardBtn.Disable() 줄에 NoneType has no attribute Disable 오류가 반환됩니다. wx.Wizard 생성자를 사용하면 페이지가 전혀 표시되지 않습니다.

위의 문제점 외에도 다른 명확한 질문이 있습니다. PyWizardPagewx.Wizard의 차이점은 무엇입니까?

+0

당신이'page1.GetNext() 안()'를 시도은? –

+0

@ 조란 비즐리 : 아니에요. 그냥 시도하고 다음 단추 대신 전체 페이지를 사용할 수 없게합니다. 그리고 나서'page1.GetNext(). FindWindowById (wx.ID_FORWARD) .Disable()'을 시도하고,'NoneType 객체에는 속성이 없습니다. Disable' – noblerare

+0

:/그 모듈을 가지고있는 wx 버전을 사용하지 마라. –

답변

0

이것은 부적절한 행동입니다. 이렇게하는 방법은 여러 가지가있을 것이라고 확신하지만 wx.Timer를 사용하여 텍스트 컨트롤에 값이 있는지 확인하고 확인합니다. 그럴 경우 버튼을 다시 활성화하십시오. 그건 그렇고, 얼마 전 버튼을 사용 불가능으로 설정했기 때문에 내가 준입니다. 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 has no attribute Disable'라는 오류가있어서 매우 실망 스럽습니다. – noblerare

+0

Wizard 클래스의 인스턴스를 사용하여 FindWindowById를 호출하는지 확인하십시오. 또한 세 번째 페이지의 경우 세 번째 페이지에 도달했을 때만 해당 통화를 실행하고 싶다고 생각합니다. 따라서 변화하는 페이지 이벤트에 바인딩하고 그것을 실행하기 전에 어떤 페이지를 확인하십시오. –

+0

의견을 보내 주셔서 감사합니다. 나는 내 코드를 좀더 들여다 보았고, 당신의 구조처럼 보이게 만들었다. 그리고 나서 내 문제의 핵심이 될지도 모르는 것처럼 보였다. 그래서 나는 그것을 나의 질문의 맨 아래에 편집으로 썼다. 당신의 도움을 주셔서 감사합니다! – noblerare

관련 문제