Thi*_*oln 5 python loops global-variables python-3.x
在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()
Run Code Online (Sandbox Code Playgroud)
这里的问题是你的while循环一直在运行,这意味着你的代码的其余部分都不会运行。这包括 Tkinter GUI,这意味着您的程序不会响应任何用户事件,包括按钮单击,因此endloop永远不会被调用。
更一般地说,在 GUI 程序中,您确实不能有一个永远运行的函数,甚至不能运行超过几分之一秒。单线程程序一次只能做一件事;如果它正在做的是永远循环,那么它就不会做任何其他事情。
\n\n所以,你可以做什么?
\n\n有两个基本选项:
\n\n将循环放在后台线程上。这意味着现在必须显式同步任何共享数据,并且意味着循环不能触及任何 GUI 小部件\xe2\x80\x94,但就您而言,事实证明这非常简单。
打破循环。让它只执行一次迭代(或者说 100 次迭代,如果它们真的很快的话),然后使用after或after_idle要求 Tkinter 调用一个执行另一次迭代(或 100 次迭代)的函数,然后after再次执行,如此继续,直到全部完成。
我将在这里向您展示如何执行第一个操作。
\n\nimport threading\nfrom tkinter import*\nroot = Tk()\n\ndef real_loop():\n while True:\n with superman_lock:\n if not superman:\n return\n print("It\'s doing something")\ndef loop():\n global superman\n global superman_lock\n superman=False\n superman_lock = threading.Lock()\n thread = threading.Thread(target=real_loop, daemon=True)\ndef endloop():\n global superman\n with superman_lock:\n superman=True\n\nbtn_1 = Button(root, text="stop", command=endloop)\nbtn_1.pack()\nbtn_2 = Button(root, text="start", command=loop)\nbtn_2.pack()\nRun Code Online (Sandbox Code Playgroud)\n\n对于唯一共享数据是“停止”标志的情况,Condition或Event通常比 更好Lock。这些threading文档解释了不同类型的同步对象之间的差异,但并不是真正的介绍性级别。关于监视器的维基百科文章可能是一个更好的学习起点,但是如果您能找到关于多线程的好教程(不一定是特定于 Python 的;Python 具有与 C pthreads 库、C++ Boost 库、 Java stdlib 等),那可能会更好。
有关更详细的讨论,请参阅为什么 GUI 应用程序冻结。
\n| 归档时间: |
|
| 查看次数: |
2939 次 |
| 最近记录: |