2015-09-28 2 views
1

Я создал собственный виджет с классом (myEntry), который наследуется от Entry. Когда я создаю экземпляр myEntry, его методы работают нормально, но когда я пытаюсь получить его атрибуты, вместо этого я получаю атрибут AttributeError.AttributeError при попытке получить атрибут из пользовательского виджета

Ниже приведена упрощенная версия кода. Я написал это, чтобы проверить этот класс и попытаться выяснить, что я делаю неправильно. Если я нажму на btTest1, я получаю «Джон Смит». Если я нажму на btTest2, я получу «Это тоже работает». Когда я нажимаю на btTest3, хотя, я получаю следующее:

Exception in Tkinter callback 
Traceback (most recent call last): 
    File "C:\Python34\lib\tkinter\__init__.py", line 1533, in __call__ 
return self.func(*args) 
    File "C:/Users/Raquel/Documents/Controle de Pedidos/CP2/teste.py", line 15, in <lambda> 
    btTest3 = Button(myFrame, text="Get value", command=lambda: print(txtTest.myValue)) 
AttributeError: 'myEntry' object has no attribute 'myValue' 

Таким образом, кажется, что я могу получить значение атрибута FULLNAME х (экземпляр класса Person) с x.fullName, но я могу Получать значение атрибута myValue txtTest (экземпляр myEntry) с помощью txtTest.myValue? Что мне здесь не хватает?

from tkinter import * 

class main(Frame): 
    def __init__(self, *args, **kwargs): 
     Frame.__init__(self, *args, **kwargs) 

     x = Person("John Smith") 
     myFrame = Frame(self, bd=10) 
     myFrame.grid(row=0, column=0, sticky=NSEW) 
     lbTest = Label(myFrame, text="My field*:") 
     vTest = StringVar() 
     txtTest = myEntry(myFrame, vTest, "testing") 
     btTest1 = Button(myFrame, text="Get full name", command=lambda: print(x.fullName)) 
     btTest2 = Button(myFrame, text="Show", command=lambda: txtTest.show()) 
     btTest3 = Button(myFrame, text="Get value", command=lambda: print(txtTest.myValue)) 
     lbTest.grid(row=0, column=0, sticky=W) 
     txtTest.grid(row=0, column=1, sticky=W) 
     btTest1.grid(row=1, column=0) 
     btTest2.grid(row=1, column=1) 
     btTest3.grid(row=1, column=2) 

class myEntry(Entry): 
    def __init__(self, master, myVar, myValue): 
     super().__init__(master, textvariable=myVar) 
     self = Entry(master, textvariable=myVar) 
     self.myValue = myValue 

    def show(self): 
     print("This works, too.") 

class Person(): 
    def __init__(self, fullName): 
     self.fullName = fullName 

if __name__ == "__main__": 
    root = Tk() 
    main(root).pack(side=TOP, fill=BOTH, expand=True) 
    root.mainloop() 

ответ

3

Проблема в том, что линии -

self = Entry(master, textvariable=myVar) 

Вы изменяете локальную переменную self на новый Entry объект, который вы создаете, а затем установив атрибут .myValue для него. Исходный объект myEntry не имеет этого атрибута, только новый объект Entry, который вы создаете, имеет его, но после этого он просто отбрасывается.

Вам действительно не нужна вышеуказанная линия, только линия super().__init__(master, textvariable=myVar) достаточно хороша. Вы можете удалить строку - self = Entry(master, textvariable=myVar). Пример:

class myEntry(Entry): 
    def __init__(self, master, myVar, myValue): 
     super().__init__(master, textvariable=myVar) 
     self.myValue = myValue 
+0

И так же все работает сейчас. Спасибо. –

Смежные вопросы