I have this program which beeps every second until it's stopped. The problem is that after I press "Start" and the beeps starts, I cannot click the "Stop" button because the window freezes. Any help is welcome.
import Tkinter, tkMessageBox, time, winsound, msvcrt
running = True
Freq = 2500
Dur = 150
top = Tkinter.Tk()
top.geometry('200x100') # Size 200, 200
sec = 0
if sec % 1 == 0:
sec += 1
running = False
startButton = Tkinter.Button(top, height=2, width=20, text ="Start", command = start)
stopButton = Tkinter.Button(top, height=2, width=20, text ="Stop", command = stop)
There are several things wrong with your code. First of all you shouldn't use
time.sleep() in a Tkinter program because it interferes with the
mainloop(). Instead one typically uses the universal widget method
.after() to schedule a function to run after a specified delay.
Secondly you're not using global variables correctly. When you assign a value to a named variable in a function, it will create a local variable unless that name has been previous declared
global. So for instance, your
stop() function is creating a local variable named
running and setting its value to 0, not changing the value of the global variable with the same name.
The previous rule doesn't apply to just referencing (reading) the current value of a variable. That is why it was OK to not have declared
Dur globals in
Another problem is with the
sec % 1 == 0 in your
start() function. Any value
% 1 is
0. To check odd/evenness use
sec % 2.
Here's a working version which has also been reformatted to follow PEP 8 - Style Guide for Python Code more closely.
import Tkinter import tkMessageBox import time import winsound FREQ = 2500 DUR = 150 after_id = None secs = 0 def beeper(): global after_id global secs secs += 1 if secs % 2 == 0: # every other second winsound.Beep(FREQ, DUR) after_id = top.after(1000, beeper) # check again in 1 second def start(): global secs secs = 0 beeper() # start repeated checking def stop(): global after_id if after_id: top.after_cancel(after_id) after_id = None top = Tkinter.Tk() top.title('MapAwareness') top.geometry('200x100') startButton = Tkinter.Button(top, height=2, width=20, text="Start", command=start) stopButton = Tkinter.Button(top, height=2, width=20, text="Stop", command=stop) startButton.pack() stopButton.pack() top.mainloop()