单选按钮悬停错误,无法通过阻止垃圾收集 tkinter 来解决
radiobutton hovering bug that cannot be solved by preventing it from garbage collection tkinter
我正在浏览一些代码并遇到了这个,当将鼠标悬停在单选按钮上时,Checkbutton
被选中,我尝试保留对变量的引用(不需要,因为已经是全局的),但它失败了。
代码如下:
from tkinter import *
root = Tk()
text_colors = ['1','2','3','4','5','6','7','8']
rads = []
for i in range(4):
for j in range(2):
col = text_colors.pop()
val = IntVar()
root.garbage_saver = val
rads.append(Radiobutton(root,text=col,fg='red',variable=val))
rads[-1].grid(row=i,column=j)
root.mainloop()
此错误可在我的 Windows 10、Python 3.9
上重现
这是没有错误的代码:
from tkinter import *
root = Tk()
text_colors = ['1', '2', '3', '4', '5', '6', '7', '8']
rads = []
val = IntVar(root)
val.set(-1)
for i in range(4):
for j in range(2):
col = text_colors.pop()
rbutton = Radiobutton(root, text=col, fg="red", variable=val, value=i*2+j)
rbutton.grid(row=i, column=j)
rads.append(rbutton)
root.mainloop()
基本上,您会用最后一个 IntVar
对象覆盖 root.garbage_saver
和 var
变量,因此它会破坏前一个对象。该行为是由 tkinter 在垃圾收集时取消设置变量引起的。
tkinter.__init__.py
:
class Variable:
"""Class to define value holders for e.g. buttons.
Subclasses StringVar, IntVar, DoubleVar, BooleanVar are specializations
that constrain the type of the value returned from get()."""
_default = ""
_tk = None
_tclCommands = None
def __del__(self):
"""Unset the variable in Tcl."""
if self._tk is None:
return
if self._tk.getboolean(self._tk.call("info", "exists", self._name)):
self._tk.globalunsetvar(self._name)
if self._tclCommands is not None:
for name in self._tclCommands:
#print '- Tkinter: deleted command', name
self._tk.deletecommand(name)
self._tclCommands = None
注意 tkinter
调用 self._tk.globalunsetvar(self._name)
告诉 tcl/tk 取消设置变量。
Tcl/Tk docs:
"The widget sets the alternate state whenever the linked -variable is unset."
我正在浏览一些代码并遇到了这个,当将鼠标悬停在单选按钮上时,Checkbutton
被选中,我尝试保留对变量的引用(不需要,因为已经是全局的),但它失败了。
代码如下:
from tkinter import *
root = Tk()
text_colors = ['1','2','3','4','5','6','7','8']
rads = []
for i in range(4):
for j in range(2):
col = text_colors.pop()
val = IntVar()
root.garbage_saver = val
rads.append(Radiobutton(root,text=col,fg='red',variable=val))
rads[-1].grid(row=i,column=j)
root.mainloop()
此错误可在我的 Windows 10、Python 3.9
上重现这是没有错误的代码:
from tkinter import *
root = Tk()
text_colors = ['1', '2', '3', '4', '5', '6', '7', '8']
rads = []
val = IntVar(root)
val.set(-1)
for i in range(4):
for j in range(2):
col = text_colors.pop()
rbutton = Radiobutton(root, text=col, fg="red", variable=val, value=i*2+j)
rbutton.grid(row=i, column=j)
rads.append(rbutton)
root.mainloop()
基本上,您会用最后一个 IntVar
对象覆盖 root.garbage_saver
和 var
变量,因此它会破坏前一个对象。该行为是由 tkinter 在垃圾收集时取消设置变量引起的。
tkinter.__init__.py
:
class Variable:
"""Class to define value holders for e.g. buttons.
Subclasses StringVar, IntVar, DoubleVar, BooleanVar are specializations
that constrain the type of the value returned from get()."""
_default = ""
_tk = None
_tclCommands = None
def __del__(self):
"""Unset the variable in Tcl."""
if self._tk is None:
return
if self._tk.getboolean(self._tk.call("info", "exists", self._name)):
self._tk.globalunsetvar(self._name)
if self._tclCommands is not None:
for name in self._tclCommands:
#print '- Tkinter: deleted command', name
self._tk.deletecommand(name)
self._tclCommands = None
注意 tkinter
调用 self._tk.globalunsetvar(self._name)
告诉 tcl/tk 取消设置变量。
Tcl/Tk docs:
"The widget sets the alternate state whenever the linked -variable is unset."