Yuva Yuva - 3 months ago 29
Python Question

Class object has no attribute tk?

I am fairly new to python and with the help of tutorials I am trying to create a calculator but got stuck due to an error which I am unable to correct which occurs when I press a number button

from tkinter import *
root=Tk()
root.title("Yuvi's CAl")
global char

class cal():

def __init__(self):
self.string= StringVar()
root=Tk()
root.title("Yuvi's CAl")
self.string=StringVar
enter=Entry(root,textvariable=self.string)
enter.grid(row=0,column=0,columnspan=6)
values=["1","2","3","4","5","+","6","7","=","8","9","c"]
row=1
col=0
i=0
for txt in values:
if i==3:
row=3
col=0
if i==6:
row=4
col=0
if i==9:
row=5
col=0

if txt=="+":
but=Button(root,text=txt)
but.grid(row=row,column=col)
elif txt=="=":
but=Button(root,text=txt,command=lambda:self.equals)
but.grid(row=row,column=col)
elif txt=="c":
but=Button(root,text=txt,command=lambda:self.clr)
but.grid(row=row,column=col)
else:
but=Button(root,text=txt,command=lambda txt=txt:self.add(txt))
but.grid(row=row,column=col)

col+=1
i+=1
def add(self,char):
meet=self.string.get(self)
self.string.set((str(meet)) + (str(char)))


def equals(self):
result=eval(self.string.get())
self.string.set(result)
def clr(self):
self.string.set("")

ent=cal()

root.mainloop()


and this being the error when I press a number button

Traceback (most recent call last):
File "/usr/lib/python3.4/tkinter/__init__.py", line 1541, in __call__
return self.func(*args)
File "/home/yuvi/Documents/LiClipse Workspace/GUI/src/Misiio_calcuator.py", line 40, in <lambda>
but=Button(root,text=txt,command=lambda txt=txt:self.add(txt))
File "/home/yuvi/Documents/LiClipse Workspace/GUI/src/Misiio_calcuator.py", line 46, in add
meet=self.string.get(self)
File "/usr/lib/python3.4/tkinter/__init__.py", line 339, in get
value = self._tk.globalgetvar(self._name)
AttributeError: 'cal' object has no attribute '_tk'


Do rectify if any mistakes
Thank you in advance

Answer

There are several issues with your code first you should remove hiding your global vars within your __init__ as it creates two windows and only running mainloop for one of them. In addition you overwrite self.string with the StringVar class object after first creating an instance of it. So your __init__ could look like so

...
def __init__(self):
    self.string=StringVar()
    enter=Entry(root,textvariable=self.string)
    enter.grid(row=0,column=0,columnspan=6)
    values=["1","2","3","4","5","+","6","7","=","8","9","c"]
    row=1
    col=0
    i=0
...

then in your add you don't have to pass self to self.string.get, that is it should look like

...
def add(self,char):
    meet=self.string.get()
    self.string.set((str(meet)) + (str(char)))
...

Those changes fixes your exception but I guess there are still other logical mistakes in the calculator, however that's not what the question is about and fixing them wouldn't help you learning python.