在Tkinter窗口中调用包含'time.sleep()'的外部函数

时间:2012-05-12 13:40:23

标签: python tkinter

我试图通过按下Tkinter GUI中的按钮来调用外部函数;函数'插入到Text元素中。这很完美;只要没有时间紧跟time.sleep()。如果没有遵循,则文本正确更新;如果是,文本不会更新,虽然该功能似乎仍在运行循环,因为它会很乐意将文本打印到控制台。

这是我的示例脚本:

from Tkinter import *
from time import sleep

def test_function(gui_self):
    while True:
        print "Debug message"
        gui_self.main_.insert(END, "Test")


class GUI:
    def __init__(self, master):
        frame = Frame(master, width=300, height=500)
        frame.pack()
        self.main_ = Entry(frame, width=80, justify=CENTER)
        self.main_.pack()

        test_function(self)

root = Tk()
application = GUI(root)
root.mainloop()

这很有效。但是,将test_function更改为以下内容似乎搞得一团糟:

def test_function(gui_self):
    while True:
        print "Debug message"
        gui_self.main_.insert(END, "Test")
        sleep(5)

有什么建议可以解决我在这里做错的事吗?我确定这只是一个问题,作为一个相当基础的用户,我没有使用正确的语法。

作为旁注,'sleep'命令似乎也完全冻结了程序,我觉得这很烦人且没有吸引力。是否有一种方法可以暂停循环以获得可变设置(例如,var = 1(第二))的时间量,而不是'管道'线程,这将是有效的,更干净的?

感谢。

2 个答案:

答案 0 :(得分:3)

一般情况下,不要在单线程GUI中调用time.sleep,否则会导致它像您发现的那样阻塞。

处理睡眠的正确方法是使用GUI事件。

请参阅another Stack Overflow问题中的此示例,其中显示了如何使用所有TK根窗口所具有的after方法。

答案 1 :(得分:3)

我完全同意尼克克雷格 - 伍德的回答 - 不要让你的gui的主线睡觉。通常,您希望调用after来注册在(大约)X毫秒之后调用的函数。这是一个每5秒调用test_function的示例。每次调用test_function时,它都会重新注册,以便在5秒后调用。

def test_function(gui_self):
    print "Debug message"
    gui_self.main_.insert(END, "Test")
    gui_self.after(5000,test_function,gui_self)
    #the line below also should work.  As long as the item is a Tkinter widget
    #gui_self.main_.after(5000,test_function,gui_self) 

此外,完全无关,(但作为一种风格问题) - 您是否有理由在main_使用GUI而不只是main?通常,使用python关键字将尾随下划线附加到aviod name-clashes。据我所知,main不是关键字。