为什么在使用Tkinter时会出现“AttributeError: NoneType对象没有属性”?None值是从哪里来的?
我创建了一个简单的图形界面:
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
对象以及其他所有小部件的grid
、pack
和place
函数都会返回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
语句放在一起,布局会更容易理解和维护。