I've tried by now several methods found online but I can't seem to find a solution. What I want to create is to enable a while loop with a button and disable it with another button. The main issue, is that while the loop is active, it freezes my GUI when I press my "disable" button. The while loop does stop, but I have to kill the executable in task manager and restart it in order to re-enable the while loop.
Code:
from tkinter import *
import time
top = Tk()
top.title("Corsair")
top.geometry('100x100')
top.resizable(False, False)
def b1():
while True:
[MY MAIN CODE]
# if But2.is_pressed:
# break
but1 = Button(top, image = onbutton, text ="On", command = b1)
but2 = Button(top, image = offbutton, text ="Off", pady = 100, padx = 10, command = top.destroy)
but1.pack()
but2.pack()
top.mainloop()
I've tried; if But2.is_pressed to break the code, which freezes the GUI.
Make but2 to destroy top window, which freezes the GUI.
I've tried ;
x = 1
def b1():
while True:
if x == 1:
[MY MAIN CODE]
else:
break
def b2():
x = 0
but1 = Button(top, image = onbutton, text ="On", command = b1)
but2 = Button(top, image = offbutton, text ="Off", pady = 100, padx = 10, command = b2)
but3 = Button(top, text ="Exit", pady = 100, padx = 20, command = top.destroy)
CodePudding user response:
This problem was few times on Stackoverflow:
If you run long-running loop then you should run it in separate thread.
But if every loop is not so long then you could use .after(milliseconds, function_name)
at the end of function (instead of while
and sleep
) to repeat function again - and this will work as loop, and tkinter
will have time to run own mainloop
import tkinter as tk # PEP8: `import *` is not preferred
import time
# --- functions --- # PEP8: all functions before main code
def b1():
print('MY MAIN CODE')
if running:
# repeat after 100ms (0.1s)
top.after(100, b1) # funcion's name without ()
else:
print('STOP')
def b2():
global running
running = False
# --- main ---
running = True
top = tk.Tk()
but1 = tk.Button(top, text="On", command=b1) # PEP8: inside `()` use `=` without spaces
but2 = tk.Button(top, text="Off", command=b2)
but1.pack()
but2.pack()
top.mainloop()
EDIT:
If you want to use button On
to restart loop again then it may need extra function to set again running = True
import tkinter as tk # PEP8: `import *` is not preferred
import time
# --- functions --- # PEP8: all functions before main code
def b1():
global running
running = True
loop()
def loop():
print('MY MAIN CODE')
if running:
# repeat after 100ms (0.1s)
top.after(100, loop) # funcion's name without ()
else:
print('STOP')
def b2():
global running
running = False
# --- main ---
running = True
top = tk.Tk()
but1 = tk.Button(top, text="On", command=b1) # PEP8: inside `()` use `=` without spaces
but2 = tk.Button(top, text="Off", command=b2)
but1.pack()
but2.pack()
top.mainloop()