use*_*510 4 python user-interface tkinter
我是Tkinter的新手,所以如果这很容易我道歉,但我已经搜索了几个小时而无法弄明白.我想要做的是在mainloop空闲之后,我总是想调用函数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()
Run Code Online (Sandbox Code Playgroud)
应用程序处于空闲状态时,您应该每隔几分钟调用一次,而不是一直调用该函数.例如,如果你想每秒检查10次,你会做这样的事情:
def checkForGroupUpdates(self):
<do whatever you want>
self.after(100, self.checkForGroupUpdates)
Run Code Online (Sandbox Code Playgroud)
一旦你调用该函数一次,它将安排自己在100ms内再次调用.这将持续到程序退出.如果程序变为"非空闲"(即:响应按钮单击时),此函数将暂停,因为tkinter是单线程的.一旦程序再次空闲,检查将继续.
@ 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)
Run Code Online (Sandbox Code Playgroud)
要使用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)
Run Code Online (Sandbox Code Playgroud)
注意添加该self.master.update_idletasks()行.这将绘制GUI并处理按钮和按钮.否则,after_idle()将占用所有资源,而不是让GUI自动更新mainloop().
使用的替代方案
self.master.update_idletasks()
self.master.after_idle(self.poll)
Run Code Online (Sandbox Code Playgroud)
是用来:
#Method 3
self.master.update_idletasks()
self.master.after(0, self.poll)
Run Code Online (Sandbox Code Playgroud)
使用self.master.after(0, self.poll)是我的首选技术,因为它允许我轻松地将0更改为其他内容,如果我决定我不需要经常运行self.poll.通过将延迟时间增加到至少1 ms,您根本不需要再进行呼叫self.master.update_idletasks().所以,这也有效:
#Method 4
self.master.after(1, self.poll)
Run Code Online (Sandbox Code Playgroud)
还要注意,上面所有的例子,呼吁self.poll()在__init__功能就是踢它全部关闭,并存储master到self.master需要简单地让里面poll,你可以调用after或after_idle通过功能self.master.after_idle,例如.
问:这是稳定的还是有效的?
答:我使用上面的方法3运行了测试代码~21小时,并且它一直运行稳定,允许GUI可用.
问:上述每种方法的速度比较是多少?
A:
问:哪个是我首选的方法?
答:方法3或4.