Python + Tkinter:"AttributeError"
Python + Tkinter: "AttributeError"
我也没有太多使用 Python 的练习,并且有一个理解错误的基本问题:AttributeError: 'NoneType' object has no attribute '_root'
,只有在我定义 dec[ 时才会出现=25=] 变量 BEFORE 定义主要 window 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()
为什么我必须先定义 window 和 而不是 布尔变量?我从 Tkinter 中有什么不明白?
感谢大家的大力帮助和祝福
拉斯
您实际上可以在 tkinter 的 __init__.py
上查看。
StringVar
、IntVar
、DoubleVar
和 BooleanVar
都继承自 class 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
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
的实例,因为不需要在屏幕上呈现任何内容,但同样不能应用于小部件。
因此,即使您没有自己创建 Tk
实例,以下内容也不会引发错误:
import tkinter as tk
a = tk.Button(text="ABC")
b = tk.BooleanVar()
我也没有太多使用 Python 的练习,并且有一个理解错误的基本问题:AttributeError: 'NoneType' object has no attribute '_root'
,只有在我定义 dec[ 时才会出现=25=] 变量 BEFORE 定义主要 window 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()
为什么我必须先定义 window 和 而不是 布尔变量?我从 Tkinter 中有什么不明白?
感谢大家的大力帮助和祝福 拉斯
您实际上可以在 tkinter 的 __init__.py
上查看。
StringVar
、IntVar
、DoubleVar
和 BooleanVar
都继承自 class 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
所以你看到当你创建一个没有母版的新小部件时,BaseWidget
实际上会创建一个 tk
的新实例作为 _default_root
而不是 Variable
。我的猜测是没有理由只为变量创建 Tk
的实例,因为不需要在屏幕上呈现任何内容,但同样不能应用于小部件。
因此,即使您没有自己创建 Tk
实例,以下内容也不会引发错误:
import tkinter as tk
a = tk.Button(text="ABC")
b = tk.BooleanVar()