我正在组装一个tkinter gui应用程序,偶尔在加载新框架并将其添加到笔记本中时,gui会冻结呼叫以进行更新。我不确定为代码提供什么,我正在进行很多子类化,因此发布所有这些将变得荒谬,而且我不确定它是否会有用。
def _handle_events_button(self):
ntbk = self.find_notebook()
print("1: " + str(int(time.time())))
w = EventListDetailsCombo(ntbk)
print("2: " + str(int(time.time())))
w.load()
print("3: " + str(int(time.time())))
w.add_to_notebook(ntbk)
print("4: " + str(int(time.time())))
# clipboard.root.update_idletasks()
print("5: " + str(int(time.time())))
ntbk.select(w)
print("6: " + str(int(time.time())))
印刷品的输出是这样的:
# Working correctly
1: 1555952235
2: 1555952235
3: 1555952235
4: 1555952235
5: 1555952237
6: 1555952237
# Hang / Delay
1: 1555952240
2: 1555952240
3: 1555952240
4: 1555952240
5: 1555952266
6: 1555952266
也就是说,使用update_idletasks()而不使用update_idletasks()时,所有这些输出都在1-2秒内。相反,挂起发生在mainloop update_idletasks
一些注意事项:
我不确定从这里去哪里,是否有任何我可以研究的内容的指针?
编辑:因此,我经历并删除了所有对update的调用,现在它只是在此代码后挂起,我假设在主循环更新步骤中,但是我不确定如何检查该假设,因此调用了_handle_events_button函数直接从事件按钮中删除,因此在此之后,我的代码将不再存在。
编辑2:如果我将update_idletasks留在其中并在其上运行分析器,则当其正常工作时,它看起来像这样:
在挂起的运行中,所有内容看起来都一样,除了方法“ call”花费约1000ms而不是花费25000ms或更长时间,并且“ call”的调用次数大致相同。
编辑3:我在打印语句的输出中添加了内容。同样,我不能将任何此函数放入单独的线程中,因为它们都只是在准备小部件。
答案 0 :(得分:0)
如果您正在运行持久性事件循环,则不要要调用update
/ update_idletasks
。 These functions are the alternative to a persistent event loop.
从事件处理程序调用它时,实际上是在运行一个临时的嵌套事件循环。直到执行所有适用的待处理事件之前,代码都会被阻塞-还会产生其他不良影响,因为您当前事件处理程序应该执行的动作仅完成了一半,其他代码可能会看到应用程序处于不一致状态。>
答案 1 :(得分:0)
因此,在将我的头撞到桌子上很多次之后,我想我明白了。首先,似乎tkinter加载小部件的速度很慢,不确定这是否是因为我有多少个小部件(加载的每一帧不是全部,可能少于100个,也许少于50个)或由于我正在做的所有子类化(可能比我应该做的还要多)。它很烦人,但目前仍然可行。
似乎可以解决偶发冻结的问题是停止使用tkcalender datepicker小部件。一旦我将其切换为基于条目和基于框架的自定义小部件,事情就停止了冻结,现在每次加载框架所需的时间几乎相同,虽然仍然很慢,但始终如一,这是我真正需要的现在。