2014-06-05 161 views
2

我有一個程序,在某些時候打開一個新窗口(填充按鈕和Gizmo的供用戶選擇和玩耍),定義如下:攔截關閉窗口按鈕(Tkinter窗口)拋出一個Tcl錯誤

def window(self,master): 
    def close(self): 
    # change some variables 
    self.destroy() 
    top = self.top = Toplevel() 
    # Several lines of buttons 
    top.lift() 
    top.protocol("WM_DELETE_WINDOW",close(self)) 

我最初有一個關閉按鈕那裏,想包了一切很好,但我注意到,如果用戶使用的窗角的標準「X」,這個功能顯然不會被調用,並且會之後會出現很多問題。我發現了從本網站上的一些其他問題「WM_DELETE_WINDOW的建議,但它給了我一個相當奇怪的錯誤:

File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1630, in wm_protocol 
    'wm', 'protocol', self._w, name, command) 
TclError: bad window path name ".33862072" 

我認爲它在某種程度上已經得到了錯誤的窗口ID,無法趕上事件。因此,我的問題是不是真的,其次我應該如何繼續處理這個問題。

+1

以及怎麼樣'top.protocol( 「WM_DELETE_WINDOW」,self.close)' – Gogo

+1

我不完全熟悉'protocol',但如果是類似的東西'bind',那麼你」可能實際上在最後一行調用'close',而不是將其註冊爲'WM_DELETE_WINDOW'的回調函數。註冊需要參數的函數的典型解決方案是將它們封裝在一個lambda中:'top.protocol(「WM_DELETE_WINDOW」,lambda:close(self))' – Kevin

+0

@Kevin現在我完全放棄了自己的想法,現在我覺得自己像個白癡:( –

回答

0

讓我們來看看下面這行代碼:

top.protocol("WM_DELETE_WINDOW",close(self)) 

這行代碼是說「立即調用函數close(self),並分配結果到協議處理器看到問題後會立即調用close,有可能?前self已全面建立。你不想要的功能是,要在參考給函數傳遞。

closeself(而不是嵌入功能)的方法和改變調用top.protocol看起來像這樣(請注意缺少尾隨括號中):

top.protocol("WM_DELETE_WINDOW", self.close) 

如果您喜歡在嵌套功能,可以使用拉姆達:

top.protocol("WM_DELETE_WINDOW", lambda window=self: close(window))