Hello all,
I am trying to write a function for a tkinter button that when toggled begins running a continuously looping function until the same button is toggled again. The code below is where i started. When the button is pressed "looping" gets continuously printed until i close the window. However, I'd rather the function stop being called after the same button is pressed again. Thanks in advance!
from tkinter import *
def close():
win.destroy()
def loopFunction():
print("looping")
win.after(1,loopFunction)
win = Tk()
InitButton = Button(win,text='Loop Function',command= loopFunction , bg = "bisque2") #,bg='grey')
InitButton.grid(row=0, column=0, pady = 5)
win.protocol("WM_DELETE_WINDOW", close)
win.mainloop()
Tkinter buttons don't toggle. How about a checkbox?
Something like this?
import tkinter as tk
from itertools import cycle
class MainFrame(tk.Frame):
def __init__(self, *args, **kwargs):
super().__init__(*args, *kwargs)
self._timer = False
self._button1_state = cycle(("disabled", "normal"))
self._create()
self._layout()
self._binds()
def _create(self):
self.button1 = tk.Button(self, text="Button1")
def _layout(self):
self.button1.pack(padx=5, pady=5)
def _binds(self):
self.button1.bind("<ButtonRelease-1>", self._on_button1)
def _on_button1(self, event):
if not self._timer:
self.toggle_button1()
else:
self.after_cancel(self._timer)
self.button1.config(state="normal")
self._timer = None
def toggle_button1(self):
self.button1.config(state=next(self._button1_state))
self._timer = self.after(100, self.toggle_button1)
def main():
app = tk.Tk()
mainframe = MainFrame(app)
mainframe.pack()
app.mainloop()
if __name__ == "__main__":
main()
(Oct-01-2021, 03:38 AM)deanhystad Wrote: [ -> ]Tkinter buttons don't toggle. How about a checkbox?
Yes, that's the main issue here. I usually pass a variable to keep track of the button state, but not so in this case. After seeing the solution regarding the button, and how much code it takes, I am very interested in how you would do this with a check box.
Do as you were doing, but only call loopFunction if the checkbox is ckecked
I miss read the requirements, I thought you wanted a button toggle on and off a continuously
Here is some shorter code hopefully more in line with what you asked for.
Note: if the
loop_function
does anything that takes too long it will block the GUI event loop see the following
[Tkinter] How to deal with code that blocks the mainloop, freezing the gui
import tkinter as tk
def loop_function():
print("looping")
class MainFrame(tk.Frame):
def __init__(self, *args, **kwargs):
super().__init__(*args, *kwargs)
self._looping = False
button1 = tk.Button(self, text="Button1", command=self._on_button1)
button1.pack(padx=5, pady=5)
self._timer()
def _on_button1(self):
self._looping = not self._looping
def _timer(self):
if self._looping:
loop_function()
self.after(100, self._timer)
def main():
app = tk.Tk()
mainframe = MainFrame(app)
mainframe.pack()
app.mainloop()
if __name__ == "__main__":
main()