为什么在使用Tkinter时会出现“AttributeError: NoneType对象没有属性”?None值是从哪里来的?

87 投票
4 回答
143441 浏览
提问于 2025-04-15 12:46

我创建了一个简单的图形界面:

from tkinter import *

root = Tk()

def grabText(event):
    print(entryBox.get())    

entryBox = Entry(root, width=60).grid(row=2, column=1, sticky=W)

grabBtn = Button(root, text="Grab")
grabBtn.grid(row=8, column=1)
grabBtn.bind('<Button-1>', grabText)

root.mainloop()

当我点击 Grab 按钮时,出现了一个错误:

C:\Python> python.exe myFiles\testBed.py
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python\lib\lib-tk\Tkinter.py", line 1403, in __call__
    return self.func(*args)
  File "myFiles\testBed.py", line 10, in grabText
    if entryBox.get().strip()=="":
AttributeError: 'NoneType' object has no attribute 'get'

为什么 entryBox 被设置为 None 呢?


另外可以参考 为什么我会得到 AttributeError: 'NoneType' 对象没有属性 'something'? 来了解一般情况。

4 个回答

6

对于Python3.8+版本,这里有一个替代方案,可以把所有内容放在一行里,使用海象运算符

(entryBox := Entry(root, width=60)).grid(row=2, column=1, sticky=W)

现在entryBox将指向Entry这个小部件,并且也会被打包。

关于每行字符数的管理,我可以建议你使用这样的方式:

(var := Button(
    text='fine', command=some_func, width=20, height=15, activebackground='grey'
)).grid(row=0, column=0, columnspan=0, rowspan=0, sticky='news')

不过在那种情况下,倒不如像其他答案建议的那样“正常”处理。

来源:

17

把这一行:

entryBox=Entry(root,width=60).grid(row=2, column=1,sticky=W)

改成这两行:

entryBox=Entry(root,width=60)
entryBox.grid(row=2, column=1,sticky=W)

就像你已经正确处理的 grabBtn 一样!

147

Entry对象以及其他所有小部件的gridpackplace函数都会返回None。在Python中,当你写a().b()时,结果就是b()返回的内容。因此,Entry(...).grid(...)会返回None

你应该把这行代码分成两行,像这样:

entryBox = Entry(root, width=60)
entryBox.grid(row=2, column=1, sticky=W)

这样做的话,你就可以把Entry的引用存储在entryBox里,并且它的布局也会像你预期的那样。这还有一个额外的好处,就是如果你把所有的grid和/或pack语句放在一起,布局会更容易理解和维护。

撰写回答