如何在tkinter的后台运行一个函数

Dem*_*nto 9 python tkinter

我是GUI编程的新手,我想用tkinter编写一个Python程序.我想要它做的就是在后台运行一个可以通过GUI影响的简单函数.

该功能从0到无穷大计数,直到按下按钮.至少这就是我想要的.但我不知道如何在后台运行此函数,因为tkinter的mainloop()始终具有控制权.如果我在无限循环中启动该函数,则无法执行mainloop()并且GUI已死.

我希望在每个循环后将控制权返回给mainloop(),但是如何在没有用户触发事件的情况下将控制从mainloop()恢复到runapp-function?

以下是一些杀死GUI的示例代码:

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)
Run Code Online (Sandbox Code Playgroud)

Bry*_*ley 8

基于事件的编程在概念上很简单.试想一下,在程序文件的末尾是一个简单的无限循环:

while <we have not been told to exit>:
    <pull an event off of the queue>
    <process the event>
Run Code Online (Sandbox Code Playgroud)

因此,您需要做的就是不断地运行一些小任务,将其分解为一口大小的碎片并将这些碎片放在事件队列中.每次循环时,计算的下一次迭代将自动执行.

您可以使用after方法将对象放在事件队列中.因此,创建一个递增数字的方法,然后重新安排自己在几毫秒后运行.它看起来像:

def add_one(self):
    self.counter += 1
    self.after(1000, self.add_one)
Run Code Online (Sandbox Code Playgroud)

以上将每秒更新一次计数器.当你的程序初始化时,你只需要调用一次,然后在它再次调用之后再调用它等.

此方法仅在您将大问题(在您的情况下"永远计数")分解为小步骤("添加一个")时才有效.如果您正在执行类似慢速数据库查询或大量计算的操作,则此技术不一定有效.


Mic*_*lon 4

您将在另一个问题Tkinter locks python when Icon returned and tk.mainloop in a thread 中找到答案。

简而言之,您需要有两个线程,一个用于 tkinter,一个用于后台任务。

  • 对于这个简单的程序,绝对不需要使用线程。这就像用电锯杀死蚂蚁一样。 (2认同)