Tkinter: AttributeError: объект NoneType не имеет атрибута <имя атрибута>

Я создал этот простой графический интерфейс:

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?

Ответ 1

Функции grid, pack и place объекта Entry и всех других виджетов возвращают 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 в блоках.

Ответ 2

Измените эту строку:

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 !