Python tkinter.ttk 组合框在退出时抛出异常

标签 python combobox tkinter ttk

在我的 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 绑定(bind)代码的问题。

典型 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.

基本上,在最后一个窗口关闭且 Tk 完成后,带有 after 的延迟调用不会被取消,也无法完成,因为过程/函数“winfo”不再存在。当您运行 IDLE 时,仍然有一个窗口,因此 Tk 不会最终确定,并且不会显示错误。

您可以通过绑定(bind) 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()

关于Python tkinter.ttk 组合框在退出时抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15448914/

相关文章:

python - 在 Flask 框架中设置全局属性

python - 重命名西里尔文件名

python - Python中的Tkinter OpenGL上下文

python - !EXE Tkinter 问题 : datas are LOST when I quit the program

python - Tkinter 框架不填充剩余空间

python - 在 python 3 中使用全局变量

python - FFMPEG Streaming 抽动低比特率

带有预先输入和分层项目的 Javascript 组合框

c# - Silverlight ComboBox 绑定(bind)到 IEnumerable<BitmapImage>,其中图像从服务器下载

java - 我如何限制用户使用组合框中某些项目的选择,以便一旦超过它就会给出错误或禁用java中的选项?