【发布时间】:2021-08-27 13:43:03
【问题描述】:
我们的应用程序(基于 Python 的、cythonised 和打包以便在未安装 Python 的计算机上使用)具有基于 PySimpleGUI / Tkinter 端口的 GUI。
在 macOS 中,我们有时会遇到极其缓慢的启动。在我的 Mac 上,从应用程序启动到主窗口完全呈现并准备好使用它只需要大约 2-3 秒。但在一些同事的 Mac 上,有时需要 45 秒甚至几分钟。我们在应用程序的早期版本中遇到了这个问题,但在 5 月份通过添加一个启动窗口解决了这个问题,如PySimpleGUI / Tk: very slow startup on Mac 中所述。新版本(= 带有启动窗口)总是在不同地方的所有可用计算机上快速启动(2-3 秒),但随后(虽然我们没有更改应用程序中的任何内容),慢启动问题再次出现- 仅在某些 Mac 上,甚至取决于位置:在我同事的计算机上,应用程序始终以最大启动。工作时 3 秒,但在家时 45 秒以上。
我们的应用有 Mac、Windows 和 Linux 版本。只有 Mac 版本有这个问题(迄今为止从未在 Win、Linux 下观察到,也从未在 Mac 上的 Win/Linux 模拟器中观察到),仅在某些计算机上与某些位置结合使用。在工作中,我们团队使用的所有计算机都很快,但在我们的一些客人的计算机上却很慢;对我的同事来说,在(她)家慢慢来;在(我的)家里,在我的电脑上很快,但在另一台电脑上很慢。这让我完全困惑!
我在代码中添加了很多日志记录,以便能够查看代码的哪些部分需要花费大量时间。只有一次网络交互(许可证验证),而且似乎并不慢:整个功能(建立连接、检索数据、处理数据、关闭连接)即使启动 45 秒以上也不会超过 2 秒.我们可以看到的所有延迟都与主窗口刷新有关:
logging.info('.created background window', session_log=True)
main_window.refresh()
logging.info('.refreshed main window', session_log=True)
只是这个refresh() 在那些缓慢的启动中需要 3-10 秒甚至更多时间。它是 PySimpleGUI 的一个函数,定义如下:
def refresh(self):
if self.TKrootDestroyed:
return self
try:
rc = self.TKroot.update()
except:
pass
return self
在主窗口完全渲染后,同样的函数被多次使用,但它们再也不会慢了;它始终处于应用程序的启动阶段。
所以,似乎是 Tkinter 的 update() 花了这么长时间。但为什么只在某些 Mac 上,以及(在同一台 Mac 上)为什么只在某些地方?
您是否曾在您的 GUI 中遇到过这样的行为?你有任何想法如何处理它?
如果有任何提示,我将不胜感激。
【问题讨论】:
-
你试过用
.update_idletasks()替换.update()吗?调用update不仅仅是更新显示,它还处理所有未决事件。 -
@BryanOakley 感谢您的提示,我会尝试并在我同事的计算机上测试后通知您。
-
@BryanOakley 是的,它有帮助!它在我的电脑和我同事的电脑上都很好用。您能否发表您的评论作为答案,以便我接受? (我注意到我的电脑上有一个副作用:打开主窗口后,需要关闭 2 个临时窗口,
.close()(Tkinter 的.destroy())现在每个需要几秒钟;我已经解决了推迟关闭出口。)
标签: python tkinter macos-big-sur pysimplegui