While 循环锁定应用程序
- 2025-02-18 09:23:00
- admin 原创
- 83
问题描述:
我已经为我正在开发的一个应用程序绞尽脑汁了一段时间。经过几个小时的调试,界面锁定,其他任何事情都无法发生,我发现这是可怕的 While 循环。请参阅下面的示例并运行它。当您通过单击按钮启动 while 循环时,您无法在屏幕上执行任何其他操作。在这种情况下,它只是一个需要按下的简单警报按钮。
from Tkinter import *
import tkMessageBox
root = Tk()
root.geometry("450x250+300+300")
root.title("Raspberry PI Test")
def myloop():
count = 0
while (count < 500):
print 'The count is:', count
count = count + 1
print "Good bye!"
def mymessage():
tkMessageBox.showinfo(title="Alert", message="Hello World!")
buttonLoop = Button(root, text="Start Loop", command=myloop)
buttonLoop.place(x=5, y=15)
buttonMessage = Button(root, text="Start Loop", command=mymessage)
buttonMessage.place(x=85, y=15)
root.mainloop()
我如何才能让一个循环一直运行到计数完成,同时还能在我的应用程序中执行其他任务?我还应该注意,我曾尝试使用线程执行同样的操作,但效果不佳。UI 仍在等待 While 循环结束,然后您才能执行任何操作。
解决方案 1:
现在我更好地了解了你想要什么(秒表),我会推荐 root.after 命令
from Tkinter import *
import tkMessageBox
import threading
import time
root = Tk()
root.geometry("450x250+300+300")
root.title("Raspberry PI Test")
print dir(root)
count = 0
def start_counter():
global count
count = 500
root.after(1,update_counter)
def update_counter():
global count
count -= 1
if count < 0:
count_complete()
else:
root.after(1,update_counter)
def count_complete():
print "DONE COUNTING!! ... I am now back in the main thread"
def mymessage():
tkMessageBox.showinfo(title="Alert", message="Hello World!")
buttonLoop = Button(root, text="Start Loop", command=myloop)
buttonLoop.place(x=5, y=15)
buttonMessage = Button(root, text="Start Loop", command=mymessage)
buttonMessage.place(x=85, y=15)
root.mainloop()
(以下为原答案)
使用线程
from Tkinter import *
import tkMessageBox
import threading
import time
root = Tk()
root.geometry("450x250+300+300")
root.title("Raspberry PI Test")
print dir(root)
def myloop():
def run():
count = 0
while (count < 500) and root.wm_state():
print 'The count is:', count
count = count + 1
time.sleep(1)
root.after(1,count_complete)
thread = threading.Thread(target=run)
thread.start()
def count_complete():
print "DONE COUNTING!! ... I am now back in the main thread"
def mymessage():
tkMessageBox.showinfo(title="Alert", message="Hello World!")
buttonLoop = Button(root, text="Start Loop", command=myloop)
buttonLoop.place(x=5, y=15)
buttonMessage = Button(root, text="Start Loop", command=mymessage)
buttonMessage.place(x=85, y=15)
root.mainloop()
请注意,当您显示信息框时,它将在 Windows API 级别阻塞,因此线程计数将等到它关闭...为了解决这个问题,我认为你可以用多处理替换线程
解决方案 2:
我对 TKinter 了解不多,但从我的阅读中可以清楚地看出,您需要在 while 循环中使用一些 TKinter 方法来更新文本框。TKinter 在事件循环中运行,因此您必须从代码中发送信号才能重新进入 TKinter 的执行。
您已经出色地发现while
循环阻碍了UI 更新的执行。因此,您无需线程化,只需暂停counting's
执行并让TKinter
UI 更新即可。
本教程提供了一个很好的例子。关键是在第 24 行,他调用了root.update
它,我相信这会中断你的程序,让 TKinter 完成它的工作。
解决方案 3:
以下是最终代码,仅用于证明线程有效。计数在发生的同时显示在屏幕上。再次感谢 Joran!
from Tkinter import *
import tkMessageBox
import threading
import time
root = Tk()
root.geometry("450x250+300+300")
root.title("Raspberry PI Test")
showResults = StringVar()
showResults.set('0')
print dir(root)
def myloop():
def run():
count = 0
while (count < 1000) and root.wm_state():
print 'The count is:', count
showResults.set(count)
count = count + 1
#time.sleep(1)
root.after(1,count_complete)
thread = threading.Thread(target=run)
thread.start()
def count_complete():
print "DONE COUNTING!! ... I am now back in the main thread"
def mymessage():
tkMessageBox.showinfo(title="Alert", message="Hello World!")
buttonLoop = Button(root, text="Start Loop", command=myloop)
buttonLoop.place(x=5, y=15)
buttonMessage = Button(root, text="Message", command=mymessage)
buttonMessage.place(x=85, y=15)
l2 = Label(root, width=15, height=4, font=("Helvetica", 16), textvariable=showResults, background="black", fg="green")
l2.place(x=15, y=65)
root.mainloop()
相关推荐
热门文章
项目管理软件有哪些?
热门标签
曾咪二维码
扫码咨询,免费领取项目管理大礼包!
云禅道AD