Tkinter classes are confusing me (basic )

194 views Asked by At

I am new to python and programming in general and I have been trying to make a simple GUI program using Tkinter but it does not run and I don't understand the errors I get?

the Errors are: GUI instance has no attribute 'frame'

Global name 'frame' is not defined.

MY code, I have removed some unncessary stuff.

class GUI:
   def __init__(self,master):

        frame=Frame(master)
        frame.pack()
        self.master=master

        now=datetime.datetime.now()



        self.date=str(now.month)+':'+str(now.day)+':'+str(now.year)

        self.time1=str(now.hour)+':'+str(now.minute)+':'+str(now.second)

        temp=14
        humidity=15

        self.userinput=StringVar()

        self.password=StringVar()

        #self.geometry('250x250+200+200')

        #self.title('Controller GUI')

        date_label=Label(frame,text='Date : %s' %self.date)

        time_label=Label(frame,text='Time: %s' %self.time1)

        temp_label=Label(frame,text='Temperature: %d C'%temp)

        hum_label=Label(frame,text='Humidity: %d%%'%humidity)



        EnterMail=Label(frame,text='Enter Gmail username:')

        EnterPass=Label(frame,text='Enter password:')


        self.mail_box=Entry(frame,textvariable=self.userinput)

        self.pass_box=Entry(frame,textvariable=self.password)


        self.EnterButton=Button(frame,text='Enter',command=self.printer)

        self.StartAlarm=Button(frame,text='Start Alarm',command=self.startalarm)

        self.StopAlarm=Button(frame,text='Stop Alarm',command=self.stopalarm)

        date_label.grid(row=0,column=0,sticky=W)

        time_label.grid(row=0,column=2,sticky=E)

        temp_label.grid(row=1,column=0,sticky=W)

        hum_label.grid(row=1,column=2,sticky=E)

        EnterMail.grid(row=4,column=0,sticky=W)

        EnterPass.grid(row=5,column=0,sticky=W)

        self.mail_box.grid(row=4,column=2)

        self.pass_box.grid(row=5,column=2)

        self.EnterButton.grid(row=7,column=0)

        self.StartAlarm.grid(row=8,column=0)

        self.StopAlarm.grid(row=10,column=0)

        mainloop()

    def startalarm(self):
        alarmlabel=Label(self.frame,text='Alarm Activated')
        alarmlabel.grid(row=11,column=0)
        GPIO.output(18,GPIO.HIGH)
        return


    def stopalarm(self):
        alarmlabel=Label(frame,text='Alarm Deactivated')
        alarmlabel.grid(row=11,column=0)
        GPIO.output(18,GPIO.LOW)
        return


    def printer(self):  # prints user input
        self.username=self.userinput.get()
        self.MailPass=self.password.get()
        print username
        print MailPass
        mail = int(feedparser.parse("https://" + self.username + ":" +
        self.MailPass +"@mail.google.com/gmail/feed/atom")["feed"]["fullcount"])

        mail_label=Label(frame,text='Email: %d unread emails' %self.mail)
        mail_label.grid(row=2,column=0,sticky=W)

        return

        root=Tk()
      app=GUI(master=root)

the website messed up some of the indentation.

2

There are 2 answers

2
aIKid On BEST ANSWER

Change every single frame in your functions to self.frame. It should fix the problem. This makes it an instance variable.

When you defined frame in __init__, you're only defining it on the scope of that function, and thus can't be used in the others.

If you refer it as an instance variable, self.frame, all of your functions will have the same variable, passed from the self argument. Problem Solved!

2
Serial On

well in the __init__ you need to make frame a class variable by making it self.frame then it can be used anywhere in the class

its telling you frame isnt defined because its ony defined in the scope of the __init__ instead of the whole class

more on Classes

your last 3 lines should look like this:

root = Tk()
app = GUI(root)
root.mainloop()