如何在不冻结可执行文件的情况下使用tkinter按钮中断while循环



到目前为止,我已经尝试了网上找到的几种方法,但似乎找不到解决方案。我想创建的是用一个按钮启用while循环,用另一个按钮禁用它。主要问题是,当循环处于活动状态时,当我按下";禁用";按钮while循环确实停止了,但我必须终止任务管理器中的可执行文件并重新启动它,才能重新启用while循环。

代码:

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()

我试过了;如果按下But2.来中断代码,则会冻结GUI。

使but2破坏顶部窗口,这会冻结GUI。

我试过了;

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)

这个问题在Stackoverflow上出现过几次:

若运行长时间运行的循环,那个么应该在单独的线程中运行它。

但是,如果每个循环不那么长,那么您可以在函数末尾使用.after(milliseconds, function_name)(而不是whilesleep(来再次重复函数-这将作为循环工作,tkinter将有时间运行自己的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()

编辑:

如果您想使用按钮On再次重新启动循环,则可能需要额外的功能来再次设置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()

最新更新