如何在tkinter后台运行函数
我刚开始学习图形用户界面(GUI)编程,想用Python的tkinter库写个程序。我希望这个程序能在后台运行一个简单的功能,并且这个功能可以通过图形界面来影响。
这个功能的主要任务是从0开始数,一直数到无穷大,直到有人按下一个按钮。至少我希望它能这样做。但是我不知道怎么才能让这个功能在后台运行,因为tkinter的主循环(mainloop())一直在控制着程序。如果我让这个功能在一个无限循环中运行,主循环就无法执行,图形界面就会卡死。
我想在每次循环后把控制权还给主循环,但我该怎么在没有用户触发事件的情况下,把控制权从主循环转回到这个运行功能的函数呢?
下面是一些示例代码,这段代码会让图形界面崩溃:
from Tkinter import *
class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.button = Button(frame, text="START", command=self.runapp)
self.button.pack(side=LEFT)
self.hi_there = Button(frame, text="RESTART", command=self.restart)
self.hi_there.pack(side=LEFT)
self.runapp()
def restart(self):
print "Now we are restarting..."
def runapp(self):
counter = 0
while (1):
counter =+ 1
time.sleep(0.1)
5 个回答
试着理解这个例子:时钟在后台更新,同时更新界面(不需要两个线程)。
# use Tkinter to show a digital clock
# tested with Python24 vegaseat 10sep2006
from Tkinter import *
import time
root = Tk()
time1 = ''
clock = Label(root, font=('times', 20, 'bold'), bg='green')
clock.pack(fill=BOTH, expand=1)
def tick():
global time1
# get the current local time from the PC
time2 = time.strftime('%H:%M:%S')
# if time string has changed, update it
if time2 != time1:
time1 = time2
clock.config(text=time2)
# calls itself every 200 milliseconds
# to update the time display as needed
# could use >200 ms, but display gets jerky
clock.after(200, tick)
tick()
root.mainloop( )
来源:链接到网站
事件驱动编程的概念其实很简单。你可以想象在你的程序文件的最后,有一个简单的无限循环:
while <we have not been told to exit>:
<pull an event off of the queue>
<process the event>
所以,要让一些小任务不断运行,你只需要把它们拆分成小块,然后把这些小块放到事件队列里。每次循环时,程序会自动执行下一个计算步骤。
你可以使用after方法把对象放到事件队列中。因此,你可以创建一个方法来增加数字,然后让它自己在几毫秒后重新安排执行。看起来大概是这样的:
def add_one(self):
self.counter += 1
self.after(1000, self.add_one)
上面的代码每秒会更新一次计数器。当你的程序初始化时,你调用它一次,从那以后它会不断地自己调用自己,循环下去。
这种方法的前提是你能把一个大问题(在这个例子中是“永远计数”)拆分成小步骤(比如“加一”)。如果你在做一些像是慢速数据库查询或者大规模计算的事情,这种方法可能就不太适用了。
你可以在这个其他问题中找到答案 Tkinter加载图标时锁定python,以及tk.mainloop在一个线程中。
简单来说,你需要有两个线程,一个用来处理tkinter,另一个用来处理后台任务。