是否可以在python中结束另一个函数的函数循环? 这似乎不起作用
这是我的代码:
from tkinter import*
root = Tk()
def loop():
global superman
superman=False
while superman==False:
print("It's doing something")
def endloop():
global superman
superman=True
btn_1 = Button(root, text="stop", command=endloop)
btn_1.pack()
btn_2 = Button(root, text="start", command=loop)
btn_2.pack()
答案 0 :(得分:3)
这里的问题是你的WHERE (AccountId(CASE(AccountId) WHEN 99999 THEN <>124 ELSE =@accountId))
循环只是继续运行,这意味着你的其余代码都无法运行。这包括Tkinter GUI,这意味着您的程序不会响应任何用户事件,包括按钮点击,因此while
永远不会被调用。
更一般地说,你真的不能拥有一个只能在GUI程序中永久运行,甚至超过几分之一秒的功能。单线程程序一次只能做一件事;如果它正在做的是永远循环,那么它就没有做任何其他事情了。
那么,可以你做什么?
有两个基本选项:
将循环放在后台线程上。这意味着现在必须显式同步任何共享数据,这意味着循环不能触及任何GUI小部件 - 但在您的情况下,结果非常简单。
打破循环。让它只进行一次迭代(或者说,100次迭代,如果它们真的很快),然后使用endloop
或after
要求Tkinter调用另一次迭代的函数(或100次迭代)和after_idle
再次,依此类推,直到他们全部完成。
我会告诉你如何在这里做第一个。
after
对于唯一共享数据是“停止”标记的情况,import threading
from tkinter import*
root = Tk()
def real_loop():
while True:
with superman_lock:
if not superman:
return
print("It's doing something")
def loop():
global superman
global superman_lock
superman=False
superman_lock = threading.Lock()
thread = threading.Thread(target=real_loop, daemon=True)
def endloop():
global superman
with superman_lock:
superman=True
btn_1 = Button(root, text="stop", command=endloop)
btn_1.pack()
btn_2 = Button(root, text="start", command=loop)
btn_2.pack()
或Condition
通常优于Event
。 threading
文档解释了不同类型的同步对象之间的差异,但并不是真正的介绍级别。关于monitors的维基百科文章可能是一个更好的学习起点,但是如果你能找到一个关于多线程的好教程(不一定是特定于Python的; Python与C pthreads库有基本相同的同步对象,那么C ++提升库,Java stdlib等等,可能会更好。
有关更详细的讨论,请参阅Why your GUI app freezes。
答案 1 :(得分:1)
假设你的loop()函数在后台做了一些工作,将它放在一个单独的线程中是个好主意。 使用线程事件,您可以与线程进行交互。
此代码未经过测试,但它应该让您了解我在某些情况下如何解决此类问题:
class Worker(threading.Thread):
def __init__(self):
threading.Thread.__init__()
self.run_event = threading.Event()
def run(self):
self.run_event.wait()
while self.run_event.is_set():
print "It's doing something!"
然后你可以初始化线程,它会在启动后立即调用run()方法,并在第一行中等待run_event设置。
假设您有一个引用工作线程的全局变量,那么从按钮触发的loop()方法将如下所示:
def loop():
global worker_thread
worker_thread.run_event.set()
通过设置run_event,传递self.run_event.wait()并输入工作循环。只要设置了线程事件,此while循环就会运行。
你的endloop()可能看起来像这样:
dev endloop():
global worker_thread
worker_thread.run_event.clear()
一旦清除线程中的run_event,就不再满足while条件并退出循环。
请注意: 此代码不完整也未经过测试,但可能会让您知道如何完成。别忘了
import threading
。
希望这会有所帮助。 格尔茨