web-dev-qa-db-fra.com

Tkinter: AttributeError: l'objet NoneType n'a pas d'attribut <nom d'attribut>

J'ai créé cette interface graphique simple:

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()

J'ai l'interface utilisateur opérationnelle. Lorsque je clique sur le bouton Grab, j'obtiens l'erreur suivante sur la console:

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'

Pourquoi entryBox est-il défini sur None?

37
Arnkrishn

Les fonctions grid, pack et place de l'objet Entry et de tous les autres widgets renvoient None. Dans python lorsque vous faites a().b(), le résultat de l'expression est tout ce que b() renvoie, donc Entry(...).grid(...) renverra None.

Vous devez diviser cela sur deux lignes comme ceci:

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

De cette façon, vous obtenez votre Entry référence stockée dans entryBox et elle est disposée comme vous vous y attendez. Cela a pour effet secondaire de rendre votre mise en page plus facile à comprendre et à maintenir si vous collectez toutes vos instructions grid et/ou pack dans des blocs.

74
Nick Meharry

Modifiez cette ligne:

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

dans ces deux lignes:

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

Tout comme vous le faites déjà correctement pour grabBtn!

5
Alex Martelli