I would like to change the function and text of a button based on which radio-button is selected. Right now what’s happening is that both commands are run at the same time as soon as the application is launched rather than it being based upon which radio-button is selected.
import tkinter as tk
import time
## Time variables for the Pomodoro
pomo = 60 * 25 ## 60 seconds times number of minutes
btime = 60 * 5 ## 60
class ExampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.label = tk.Label(self, text="25:00", width=10, font="Helvetica 20")
self.label.pack()
self.remaining = 0
self.button = tk.Button(self)
self.button.pack()
pomocommand = self.button.configure(text="Pomodoro", state=tk.NORMAL, command= lambda: self.pomodoro(pomo)) #Switch back to the pomodoro timer
breakcommand = self.button.configure(text="Break", state=tk.NORMAL, command= lambda: self.breaktime(btime)) #Switch to the break timer
countercommand = self.button.configure(text="Counter", state=tk.NORMAL, command= print('cheese'))
self.radvar = tk.IntVar()
self.radvar.set('1')
self.radio = tk.Radiobutton(self, text="Pomodoro", variable = self.radvar, value=1, indicatoron=0, command = pomocommand)
self.radio.pack(anchor=tk.W)
self.radio = tk.Radiobutton(self, text="Counter", variable = self.radvar, value=2, indicatoron=0, command = countercommand)
self.radio.pack(side=tk.LEFT)
def pomodoro(self, remaining = None):
self.button.configure(state=tk.DISABLED)
if remaining is not None:
self.remaining = remaining
if self.remaining <= 0:
self.label.configure(text="Time's up!")
breakcommand
else:
self.label.configure(text= time.strftime('%M:%S', time.gmtime(self.remaining))) #Integer to 'Minutes' and 'Seconds'
self.remaining = self.remaining - 1
self.after(1000, self.pomodoro)
def breaktime(self, remaining = None):
self.button.configure(state=tk.DISABLED)
if remaining is not None:
self.remaining = remaining
if self.remaining <= 0:
self.label.configure(text="Time's up!")
pomocommand
else:
self.label.configure(text= time.strftime('%M:%S', time.gmtime(self.remaining))) #Integer to 'Minutes' and 'Seconds'
self.remaining = self.remaining - 1
self.after(1000, self.breaktime)
if __name__ == "__main__":
app = ExampleApp()
app.mainloop()
What you are doing is calling the function
self.button.configure(...)instead of passing the function itself. Here is a small example:Basically what is happening is that you are using the first example, so the function is called in
__init__, and what it is supposed to do is done there. What you want is something similar to the second, because Tkinter wants something to call (a function or anycallable). Sopomocommandandbreakshould be functions not the result of calling a function. (You can try to doprint pomocommandand see that it is not a function.)The solution is either to create a new function, or use lambdas. Here:
And you do the same for the other button. Using a lambda here is not recommended because it is a long statement (the self.button.configure part) so your code will not be readable. But I see you are using lambdas, so you might get the idea.
As a side note, be careful when using lambda like you do. Here
pomois a global variable, but if it is not, you might get into trouble. See this question. (Right now it is alright, so you can just ignore this :D).