【发布时间】:2019-06-04 00:16:55
【问题描述】:
假设我们有三个 tkinter 小部件:一个标签、一个树视图和一个选项菜单(以下简称为“菜单”)。一旦选择了一个选项,我就成功地使菜单执行了一个功能。简要函数如下所示:
def data_process():
# do something takes time
def print_data()
data_process() # do something takes time too
# print stuff to treeview
def refresh_table(self, args):
label['text'] = 'Executing' # change label text to Executing
print_data() # a func. which takes time to run
label['text'] = 'Done' # change text to Done
label = tk.Label(parent, text = 'ready')
label.pack()
menu = tk.OptionMenu(parent, var, *list, command = lambda _:refresh_table(self, args))
menu.pack()
table = tk.Treeview(parent)
table.pack()
函数print_data 将打印一些内容到树视图小部件(表格)。标签小部件就像一个状态栏,告诉用户现在发生了什么。所以我尝试做的工作流程是:
在菜单中选择一个选项并致电
refresh_table。将标签文本更改为“正在执行”。
执行
print_data并在树形视图中打印内容。print_data完成后,将标签更改为“完成”。
事情就是这样。当我选择该选项时,程序会(如预期的那样)做一些事情。但是,标签在开始时并未更改为“正在执行”。相反,当print_data 完成执行(几乎同时)时,它变为“完成”。我怀疑命令refresh_table 会在所有需求完成后影响目标小部件。因为我确实看到标签闪烁“正在执行”,但立即显示“完成”。对这种情况有什么想法吗?任何建议表示赞赏。谢谢!
【问题讨论】:
-
将标签更改为“正在执行”后尝试调用
root.update()。 -
@Kamal 先生,谢谢它有效!但我可以进一步问为什么吗?它与线程有关吗?不过只是猜测。再次感谢您。
-
如果不查看完整代码,我不能肯定地说,但我猜想当
refresh_table函数被调用时,root.mainloop()没有在执行中,所以对root.update()的调用就可以完成这项工作. -
原来
.update和.update_idletasks都可以完成这项工作,但有不同的方面。再次感谢您的快速回复! -
@Kamal 我只是注意到它可能会让人觉得好像我想直接在我的回答中处理你的评论,在我说
update_idletasks在我看来比@987654335 更好的部分@,但我想明确表示这不是我的意图——我在写答案时没有阅读你的评论。希望我没有冒犯你:-)
标签: python python-3.x oop tkinter