Puetong0815
Puetong0815

Reputation: 35

Python attribute error in a class

I want to create some frames in Tkinter, that should be updated periodically. Here is the code for on of them:

from Tkinter import *
import time
import random

class KopfFrame:
    def __init__(self,master):
        frame = Frame(master,bg="tan")
        frame.pack(side=TOP,expand=YES, fill=BOTH)
        self.ZeitLabel = Label(frame)
        self.ZeitLabel.pack(side=RIGHT, expand=NO,ipadx=2, ipady=2)
        self.refresh()

    def refresh(self):
        self.ZeitLabel.configure(text=time.strftime("%H:%M:%S"))
        # call this function again in 5 seconds
        #print(self)
        self.after(5000, self.refresh)

root = Tk()
K = KopfFrame(root)
root.mainloop()

But, when I run it, I have the error:

AttributeError: KopfFrame instance has no attribute 'after'

I am pretty sure, that the way of calling is the problem. So if someone could help me, thaf I would either be thankful for a hint to a good tutorial for functions, classes an how to call an use them.

Upvotes: 0

Views: 112

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121196

You are trying to call self.after(), with self being an instance of your KopfFrame class. That class does not have such a method defined.

Perhaps you wanted to call the Frame.after() method here. You'll need to store a reference to the Frame object you pass in first, then call after on that:

class KopfFrame:
    def __init__(self,master):
        # make frame an attribute on self
        self.frame = Frame(master, bg="tan")
        self.frame.pack(side=TOP,expand=YES, fill=BOTH)
        self.ZeitLabel = Label(self.frame)
        self.ZeitLabel.pack(side=RIGHT, expand=NO,ipadx=2, ipady=2)
        self.refresh()

    def refresh(self):
        self.ZeitLabel.configure(text=time.strftime("%H:%M:%S"))
        # now you can reach the frame and call after on that:
        self.frame.after(5000, self.refresh)

What I changed:

  • Instead of making frame only a local in the KopfFrame.__init__ method, make it an attribute on self.

  • Use the self.frame reference to the frame in KopfFrame.refresh() to access the Frame.after() method.

Upvotes: 1

Related Questions