I am writing a function which should return two other functions in it until I decide to stop it. Maybe I even want the function to run 5 hours. I write my code, and it runs perfectly except for one problem: when I click on the starting button, the button stays pressed and I cannot close the infinite loop. I want a way to stop my program without doing key-interrupting or something else. I think a button which can stop my started process would be fine.
Here is my button:
self.dugme1 = Button(text="Start ", command=self.start, fg="black", bg="green", font="bold")
self.dugme1.place(relx=0.05, rely=0.65)
Here are my functions:
def greeting(self):
print("hello")
def byee (self):
print("bye")
def start(self):
while True:
self.greeting()
self.byee()
When I click the button these will be run in the terminal infinitely until I stop them using keyboard interrupting. Is there any way to stop it using an elegant way such as a stop button?
CodePudding user response:
You can achieve this with threading. The following code demonstrates a start/stop button for an infinitely running process:
import tkinter as tk
import threading
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.stop_event = threading.Event()
self.thread = threading.Thread(target = self.start, args = (self.stop_event,))
self.btn = tk.Button(self, text = "Start", command = self.start_cmd)
self.btn.pack()
def start_cmd(self):
self.btn.config(text = "Stop", command = self.stop_cmd)
self.thread.start()
def stop_cmd(self):
self.stop_event.set()
self.destroy()
def start(self, stop_event):
while not stop_event.is_set():
self.greeting()
self.byee()
def greeting(self):
print("hello")
def byee(self):
print("bye")
app = App()
app.mainloop()
CodePudding user response:
You can use threading on start function. I am sure you'll find more information about this here on over the internet.
Example below:
import threading
self.dugme1 = Button(text="Start ",
command=lambda e: threading.Thread(name='start', target=self.start, daemon=True).start(),
fg="black",
bg="green",
font="bold"
)
then you can have your start function as:
def start(self):
if self.start_running == False:
self.start_running = True
while self.start_running:
self.greeting()
self.byee()
where self.start_running
is a variable that is initially set to false at the beginning of your program (or you can set declare it first in start function with a try-except block)
the first if avoids multiple calls to the same button, calling the function more than once.
You can turn "false" the variable self.start_running
to stop the execution of start
function.
We want the thread to be daemon
, so that the function is terminated whenever main terminates.
If you don't want those function to exit abruptly, turn daemon=False, but make sure to signal self.start_running=False, before your program exits.