9

我是 Tkinter 的新手,所以如果这很容易,我深表歉意,但我已经搜索了几个小时并且无法弄清楚。我想做的是在主循环空闲后,我总是想调用函数checkForGroupUpdates()。当我运行下面的代码时,它只运行一次。我无法弄清楚每次主循环空闲时都让它运行。我很感激帮助。

from Tkinter import *
import random

class Network(Frame):  
    """ Implements a stop watch frame widget. """                                                               
    def __init__(self, parent=None, **kw):      
        Frame.__init__(self, parent, kw)
        self.makeWidgets()    

    def makeWidgets(self):                       
        """ Make the time label. """
        self._canvas = Canvas(self, width=600, height=400)
        self._canvas.pack()

    def checkForGroupUpdates(self):
        print "checking"
        h=0
        this=10
        while this>.0001:
            this=random.random()
            print h
            h=h+1
        print "checked"


def main():
    root = Tk()
    nw = Network(root)
    nw.pack(side=TOP)

    root.after_idle(nw.checkForGroupUpdates)
    root.mainloop()


if __name__ == '__main__':
    main()
4

2 回答 2

13

@user1763510,请注意,在 Bryan Oakley 的回答中,他又checkForGroupUpdates打电话self.after了。这是因为self.after只进行一次调用,因此重复调用需要让它在第一次调用调用的函数中调用自身。这样,它就不断地重复调用自己。

函数也是如此after_idle()。您必须在底部再次checkForGroupUpdates调用。after_idle()

这是 , 等的文档。after描述after_idle中甚至还有一个小例子after,这一切都清楚了。

文档:http ://effbot.org/tkinterbook/widget.htm

来自上面链接的示例,在after描述下:

#Method 1
class App:
    def __init__(self, master):
        self.master = master
        self.poll() # start polling

    def poll(self):
        ... do something ...
        self.master.after(100, self.poll)

after_idle改为使用,它看起来像这样:

#Method 2
class App:
    def __init__(self, master):
        self.master = master
        self.poll() # start polling

    def poll(self):
        ... do something ...
        self.master.update_idletasks()
        self.master.after_idle(self.poll)

注意添加的self.master.update_idletasks()行。这会绘制 GUI 并处理按钮按下和其他事情。否则,after_idle()会占用所有资源,无法让 GUI 在mainloop().

使用的替代方法

        self.master.update_idletasks()
        self.master.after_idle(self.poll)

是使用:

        #Method 3
        self.master.update_idletasks()
        self.master.after(0, self.poll)

Usingself.master.after(0, self.poll)是我的首选技术,因为如果我决定不需要经常运行 self.poll,它可以让我轻松地将 0 更改为其他值。通过将延迟时间增加到至少 1 毫秒,您根本不再需要调用self.master.update_idletasks()。所以,这也有效:

        #Method 4
        self.master.after(1, self.poll)

另请注意,对于上面的所有示例,调用self.poll()函数__init__是一切的开始,并且存储masterself.master是必要的,这样poll您就可以在内部调用afterorafter_idle函数self.master.after_idle,例如。

问:这稳定/有效吗?
答:我使用上面的方法 3 运行了大约 21 小时的测试代码,它一直运行稳定,使 GUI 可以使用。

问:以上每种方法的速度比较是多少?
A:

  • 方法一:(我没测速)
  • 方法 2:~0.44 毫秒/迭代
  • 方法 3:~0.44 毫秒/迭代
  • 方法 4:~1.61 毫秒/迭代

问:我喜欢哪种方法?
答:方法3或4。

于 2016-08-07T18:55:32.167 回答
11

与其在应用程序空闲时一直调用该函数,不如每隔几分之一秒调用一次。例如,如果您想每秒检查 10 次,您可以执行以下操作:

def checkForGroupUpdates(self):
    <do whatever you want>
    self.after(100, self.checkForGroupUpdates)

一旦您调用该函数一次,它将安排自己在 100 毫秒内再次被调用。这将一直持续到程序退出。如果程序进入“非空闲”状态(即:响应按钮单击时),此函数将暂停,因为 tkinter 是单线程的。一旦程序再次空闲,检查将继续。

于 2013-08-28T22:20:55.553 回答