我正在为我正在处理的应用程序敲打一段时间。经过几个小时试图调试接口锁定的问题,没有其他任何事情可以发生,我发现它是可怕的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()
如何在计数完成之前有一个需要运行的循环,并且仍能在我的应用程序中执行其他任务?我还应该注意到,我使用Thread尝试过同样的事情并不重要。在您可以执行任何操作之前,UI仍在等待While循环结束。
答案 0 :(得分:2)
现在我明白你想要什么(秒表)我会推荐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级别阻止的信息框时,线程计数将等到关闭...为了解决这个问题,您可以用多处理替换线程我认为
答案 1 :(得分:0)
我对TKinter并不是很了解,但从我的阅读中可以清楚地看到,你需要在while循环中使用一些TKinter方法来更新你的文本框。 TKinter在事件循环上运行,因此您必须从代码发送信号以重新输入TKinter的执行。
您发现自己的while
循环阻止执行了您的用户界面更新,您做得非常出色。因此,您需要暂停执行counting's
并让TKinter
更新用户界面,而不是线程化。
这个tutorial提供了一个很好的例子。关键是在第24行,他打电话给root.update
,我认为这违反了你的程序让TKinter做了它。
答案 2 :(得分:0)
这是最终的代码,只是为了证明该线程有效。计数在屏幕上同时显示。再次感谢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()