2016-08-17 21 views
1

我有一個wxpython對話框(包裹在一個函數調用,返回用戶選擇),我用來提示用戶「確定」,「取消」類型的問題。wxpython對話框返回值與選項銷燬

我有另一個正在運行的線程,允許用戶單擊一個按鈕並執行緊急停止(也是wxpython)。當點擊緊急停止按鈕時,它會執行一些操作,然後顯示自己的用戶對話框。

現在,假設彈出消息已經提示用戶有是/否的問題,並且在同一時間,用戶看到某事着火併決定點擊緊急停止。

我需要能夠銷燬當前的對話框問題,並最終顯示對話框是estop線程的一部分。

我創建的代碼在一個線程中啓動對話框,另一個發出一個pub.sendMessage(...)來終止對話線程,如果它在按下estop按鈕時顯示在屏幕上。

這工作得很好。

問題是,我無法從用戶對話框中得到結果(是,否,取消等),因爲線程永遠不會返回以返回用戶選擇的內容。

如果我添加一個.join()到我的代碼,我得到了用戶響應,但是如果發送一個pub.sendMessage(...),對話框不會被銷燬。

繼承人僞代碼:

1)start up thread to monitor user emergency stop button push 
2)start up test which may contain popup window (custom wxdialog) prompting user for answer 
3)return user selection from dialog if selected 
    OR if user has clicked estop button: destroy current dialog and display new dialog related to estop 

很簡單,但用的包裝功能的實現(這是給別人調用代碼,並需要提供簡單的函數調用),它顯然有點怪異。但重新實現它可能不是現在

繼承人一些代碼(均爲大類因此多數民衆贊成的一部分,爲什麼自我引用是有)

#the receiver of the pub message first: 

def DestroyUI(self): 
    print 'into destroy' 
    #self.Hide() 
    #self.Close() 
    self.Destroy() 

#these 2 fuctions are part of a different class 

def closeDialogs(self): 
    print 'into closeDialogs' 
    def destroyUI(): 
     if self.okToKill: 
      print 'closing wx dialogs' 
      pub.sendMessage("destroyUI") 
    ts = threading.Thread(target = destroyUI) 
    ts.start() 
    ts.join() 


def MB(self,blah,blah): 
    def runMB(*args): 
     self.okToKill= True 
     self.response = self.PromptUser(*args) 
     self.okToKill= False 

    tr = threading.Thread(target = runMB,args=(blah,blah)) 
    tr.start() 

    #if i add the join back in, i always return the user values 
    #but the dialog is never destroyed (if needed) before user 
    #clicks. 
    #without the join, the destroy pub send works great, but the 
    #user values are never returned 
    #tr.join() 

    return self.response 

我已經使用隊列,多處理池嘗試,但問題飛與那些是q.get()和async_result()。get()都阻塞,直到用戶點擊,因此不會允許銷燬按需工作。

id喜歡弄清楚的是如果用戶點擊按鈕,如何獲取用戶值,但也能夠銷燬當前對話框並顯示新的緊急停止對話框(帶有自定義按鈕)。

我希望的wxPython剛剛有了一個CLOSEALL():)

而且,我已經嘗試基於標題名稱關閉窗戶,而工作,它軟管我的WX實例在下一個對話框。

任何想法? 感謝

+0

你的問題是什麼?我不明白 –

+0

附近的帖子:「如果用戶點擊按鈕,如何獲得用戶值,但是也能夠銷燬當前對話框並顯示新的緊急停止對話框(使用自定義按鈕)「。 – pyNewbie

+0

你做錯了什麼(我認爲)...你的不完整代碼向我們展示了你的(可能是不正確的)解決方法並不真正告訴我你正在嘗試做什麼,你的解釋並不清楚(至少對我來說)...我可以回答你的問題,如果你能幫助我理解你想做什麼(如果你必須寫一些僞代碼)(例如你可以使用'wx.CallAfter'直接從一個線程調用一個方法(方法將在主線程中運行))... pubsub很酷,但你不需要它,只是因爲你在做線程 –

回答

2

,因爲我真的不明白你問什麼,我反而會解決「我希望的wxPython剛剛有了一個CLOSEALL():)」

def wx_closeAll(): 
    for win in wx.GetTopLevelWindows(): 
     win.Destroy() 

def closeAllButPrimary(): 
    for win in wx.GetTopLevelWindows(): 
     if win != wx.GetTopLevelWindow(): 
      win.Destroy() 

這將關閉所有幀和父對象爲None的對話框...如果您爲框架或對話框設置父級,則在父級窗口關閉時該對話框將被關閉

+0

感謝您的代碼。這實際上讓我得到了我想要的東西,而沒有所有的酒吧和銷燬電話。雖然這可能是老牌wx編碼器的常識,但我並沒有意識到這一點,所以希望它能幫助其他人!再次感謝! – pyNewbie

2

從線程執行GUI並不是一個好主意,並且幾乎總是會產生意外的結果。

爲了顯示線程中的消息框,您需要讓線程詢問主線程以顯示消息框。

這樣做使用的功能wx.CallAfter

+1

好的答案....我不知何故也認爲'wx.CallAfter'也是正確的答案以及 –

+0

我的線程運行良好,除了這個,但嘗試了一個簡單的wx.CallAfter()沒有成功。不久之後發生了什麼試驗 – pyNewbie