我也没有太多的 Python 实践,并且有一个理解错误的基本问题:AttributeError: 'NoneType' object has no attribute '_root'
,它只出现在我定义时dec 变量 BEFORE 定义主窗口 win:
import tkinter as tk
from tkinter import ttk
from tkinter import *
# This variable must be defined AFTER definition of the Tk() window!
dec = tk.BooleanVar()
# Main window
win = Tk()
# # This variable must be defined AFTER definition of the Tk() window!
# dec = tk.BooleanVar()
decreaseButton = Checkbutton(win, text = "Decrease (optional)", variable = dec)
decreaseButton.grid(row=1, column=1, sticky='W')
# Runs the event loop of Tkinter
win.mainloop()
为什么我必须先定义窗口,然后定义 bool 变量?我对 Tkinter 有什么不理解的?
感谢大家的大力帮助,并致以最良好的祝愿 拉斯
最佳答案
您实际上可以在 tkinter 的 __init__.py
中查看它。
StringVar
、IntVar
、DoubleVar
和BooleanVar
都继承自类Variable
:
class Variable:
...
_default = ""
_tk = None
_tclCommands = None
def __init__(self, master=None, value=None, name=None):
...
if name is not None and not isinstance(name, str):
raise TypeError("name must be a string")
global _varnum
if not master:
master = _default_root
self._root = master._root()
self._tk = master.tk
...
所以你看到当创建一个 tkinter 变量时,它会查找存储为全局变量 _default_root
的 master
(即 None
如果您尚未创建 tk
实例),这就是您收到 AttributeError
的原因。
但您可能会问,为什么这不适用于小部件?这是因为 Widgets
继承自一个名为 BaseWidgets
的不同基类:
class BaseWidget(Misc):
...
def _setup(self, master, cnf):
...
if _support_default_root:
global _default_root
if not master:
if not _default_root:
_default_root = Tk() <--- create a new instance of `Tk`
master = _default_root
所以你看到当你创建一个没有master的新小部件时,BaseWidget
实际上会创建一个新的tk
实例作为_default_root
到 变量
。我的猜测是没有理由只为变量创建 Tk
的实例,因为不需要在屏幕上呈现任何内容,但同样不能应用于小部件。
因此,即使您没有自己创建 Tk
实例,以下内容也不会引发错误:
import tkinter as tk
a = tk.Button(text="ABC")
b = tk.BooleanVar()
关于Python + Tkinter : "AttributeError",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67353112/