簡體   English   中英

Python tkinter.ttk組合框在退出時引發異常

[英]Python tkinter.ttk combobox throws exception on quit

在我的Python 3.3代碼中,我使用了ttk庫中的一些組合框,它們的功能很好,但是如果使用其中任何一個,當我用X按鈕關閉窗口時都會出現異常。 這是一個例子:

from tkinter import Tk,Label,Button
from tkinter import ttk
from tkinter.ttk import Combobox

def cbox_do(event):
    'Used for cbox.'
    clabel.config(text=cbox.get())

a = Tk()
cbox = Combobox(a, value=('Luke','Biggs','Wedge'), takefocus=0)
cbox.bind("<<ComboboxSelected>>", cbox_do)
cbox.pack()
clabel = Label(a)
clabel.pack()
a.mainloop()

如果您關閉它而不選擇一個值,那么一切都很好,但是在選擇一個值之后嘗試關閉它,它會退出,但會在python命令行中顯示以下錯誤:

can't invoke "winfo" command:  application has been destroyed
    while executing
"winfo exists $w"
    (procedure "ttk::entry::AutoScroll" line 3)
    invoked from within
"ttk::entry::AutoScroll .41024560"
    (in namespace inscope "::" script line 1)
    invoked from within
"::namespace inscope :: {ttk::entry::AutoScroll .41024560}"
    ("uplevel" body line 1)
    invoked from within
"uplevel #0 $Repeat(script)"
    (procedure "ttk::Repeat" line 3)
    invoked from within
"ttk::Repeat"
    ("after" script)

我該如何解決? 謝謝您能提供的任何幫助。

更新1:我的Python版本是v3.3,我使用捆綁的Tcl / Tk和Tkinter。 我嘗試了x86和x64版本。

更新2:僅當我從命令行運行腳本時,才會引發異常。 它不會顯示在空閑狀態。

這是ttk中使用的Tcl / Tk綁定代碼的問題。

在典型的python Tkinter安裝中,tcl / tk8.5 / ttk / entry.tcl文件中的注釋提示了該問題:

## AutoScroll
#   Called repeatedly when the mouse is outside an entry window
#   with Button 1 down.  Scroll the window left or right,
#   depending on where the mouse is, and extend the selection
#   according to the current selection mode.
#
# TODO: AutoScroll should repeat faster (50ms) than normal autorepeat.
# TODO: Need a way for Repeat scripts to cancel themselves.

基本上,帶有after的延遲調用不會被取消,並且在關閉最后一個窗口並完成Tk之后無法再完成,因為過程/函數“ winfo”不再存在。 當您運行IDLE時,仍然有一個窗口,因此Tk不會完成,並且不會顯示錯誤。

您可以通過在WM_DELETE_WINDOW消息上綁定來解決此問題,該消息將停止重復計時器。 的代碼將是(在Tcl / Tk中):

proc shutdown_ttk_repeat {args} {
    ::ttk::CancelRepeat
}
wm protocol . WM_DELETE_WINDOW shutdown_ttk_repeat

對於Tkinter,它應該以類似的方式工作:

from tkinter import Tk,Label,Button
from tkinter import ttk
from tkinter.ttk import Combobox

def cbox_do(event):
    'Used for cbox.'
    clabel.config(text=cbox.get())

a = Tk()
cbox = Combobox(a, value=('Luke','Biggs','Wedge'), takefocus=0)
cbox.bind("<<ComboboxSelected>>", cbox_do)
cbox.pack()
clabel = Label(a)
clabel.pack()

def shutdown_ttk_repeat():
    a.eval('::ttk::CancelRepeat')
    a.destroy()

a.protocol("WM_DELETE_WINDOW", shutdown_ttk_repeat)
a.mainloop()

我最近遇到了類似的問題。 錯誤消息是完全相同的。 我通過在Exit方法中添加a.quit()解決了這一問題。 (在此方法中只有a.destroy()之前)也許您已經解決了這個問題。 但是schlenk的答案對我來說效果不佳。 所以我希望我的回答可以為這個問題提供另一個線索

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM