问题描述
我也没有太多的 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()
为什么我必须首先定义窗口然后然后定义布尔变量?我从 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 变量被创建时,它会查找一个存储为全局变量 master
的 _default_root
(如果你还没有创建一个 {{ 1}} 实例),这就是您收到 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
的新实例作为 BaseWidget
,而不是 tk
。我的猜测是没有理由只为变量创建 _default_root
的实例,因为不需要在屏幕上呈现任何内容,但同样不能应用于小部件。
因此,即使您没有自己创建 Variable
实例,以下内容也不会引发错误:
Tk