Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial

Asif Choudhury
2,086 PointsAttributeError: 'Pymodoro' object has no attribute 'stop_button'
When I am running the program, I am getting the following error
in start_timer self.stop_button.config(state=tkinter.NORMAL) AttributeError: 'Pymodoro' object has no attribute 'stop_button'
I think part of the reason of this is, self.start_button and self.stop_button has been used in 2 methods (start_timer() and stop_timer()) outside their parent method: build_buttons().
So, Python 3 interpreter is not recognizing the attributes.
What to do about it?
Thanks in advance!
3 Answers

Chris Freeman
Treehouse Moderator 68,460 PointsThe issue is in the build buttons code
. As shown in the stacktrace below, build_buttons
is calling self.start_timer
which references the stop_button
that has not yet been build by the build_buttons
code.
C:\Users\Chris\Documents\Treehouse>python pomodoro.py
Traceback (most recent call last):
File "pomodoro.py", line 90, in <module>
Pymodoro(root)
File "pomodoro.py", line 21, in __init__
self.build_buttons()
File "pomodoro.py", line 59, in build_buttons
command=self.start_timer()
File "pomodoro.py", line 80, in start_timer
self.stop_button.config(state=tkinter.NORMAL)
AttributeError: 'Pymodoro' object has no attribute 'stop_button'
The specific issue is that tkinter.Button
command argument takes a callback function. A callback is a function that will be called when the button is pushed. So a function is needed, not the execution of a function. So leave off the parens.
self.start_button=tkinter.Button(
buttons_frame,
text='Start',
command=self.start_timer # <-- no parens
)
self.stop_button=tkinter.Button(
buttons_frame,
text='Stop',
command=self.stop_timer # <-- no parens
)
That corrects the compile error. The next step is to figure out why the timer value is not being displayed.
See description of tkinter callbacks docs.
I'll leave that to you to work on. Post back if you need more help. Good luck!!

Asif Choudhury
2,086 PointsHere is my code
import tkinter
DEFAULT_GAP=60*25
class Pymodoro:
def __init__(self,master):
self.master=master
self.mainframe=tkinter.Frame(self.master, bg="white")
self.mainframe.pack(fill=tkinter.BOTH, expand=True)
self.timer_text=tkinter.StringVar()
self.time_left=tkinter.IntVar()
self.time_left.set(DEFAULT_GAP)
self.running=False
self.build_grid()
self.build_banner()
self.build_buttons()
self.build_timer()
def build_grid(self):
self.mainframe.columnconfigure(0,weight=1)
self.mainframe.rowconfigure(0,weight=0)
self.mainframe.rowconfigure(1,weight=1)
self.mainframe.rowconfigure(2,weight=0)
def build_banner(self):
banner=tkinter.Label(
self.mainframe,
bg='red',
fg='white',
text='Pymodoro',
#font info is a tuple
font=('Helvetia',24)
)
banner.grid(
row=0, column=0,
#stickiness is directional info: east, west, north, south
#the row cannot be stretched north south
# it can only be expanded east west
sticky='ew',
padx=10, pady=10
)
def build_buttons(self):
buttons_frame=tkinter.Frame(self.mainframe)
buttons_frame.grid(row=2, column=0, sticky='nsew', padx=10, pady=10)
buttons_frame.columnconfigure(0, weight=1)
buttons_frame.columnconfigure(1,weight=1)
self.start_button=tkinter.Button(
buttons_frame,
text='Start',
command=self.start_timer()
)
self.stop_button=tkinter.Button(
buttons_frame,
text='Stop',
command=self.stop_timer()
)
self.start_button.grid(row=0, column=0, sticky='ew')
self.stop_button.grid(row=0,column=1,sticky='ew')
self.stop_button.config(state=tkinter.DISABLED)
def build_timer(self):
timer=tkinter.Label(self.mainframe, text=self.timer_text.get(),font=('Helvetica',36))
timer.grid(row=1,column=0,sticky='nsew')
def start_timer(self):
self.time_left.set(DEFAULT_GAP)
self.running=True
self.stop_button.config(state=tkinter.NORMAL)
self.start_button.config(state=tkinter.DISABLED)
def stop_timer(self):
self.running=False
self.stop_button.config(state=tkinter.DISABLED)
self.start_button.config(state=tkinter.NORMAL)
if __name__=='__main__':
root=tkinter.Tk()
Pymodoro(root)
root.mainloop()
[MOD: added ```python formatting -cf]

Asif Choudhury
2,086 PointsThanks a bunch for your detailed answer. It surely was helpful to identify the rookie mistake I was making.
Best Regards.
Chris Freeman
Treehouse Moderator 68,460 PointsChris Freeman
Treehouse Moderator 68,460 PointsCan you post your code?