[英]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.