1

这个问题是我的问题Desktop GUI Loading Slow的延续。

我有一个用 wxPython 开发的桌面 GUI,它使用 sqlAlchemy 从数据库中获取许多记录查询。我将获取的记录放入 Python 字典并使用它填充 GUI。但是,由于我在后台读取数千个数据,所以 GUI 会卡住并且加载非常缓慢。现在的问题是:

  1. 我应该为每个 sqlalchemy 数据获取查询创建单独的线程吗?如果答案是肯定的,那么 wx.callAfter() 是我必须关注的方法(对于每个查询)吗?如果有人提供示例/未经测试的代码或链接,那么它将很有帮助。
  2. 有没有其他方法可以在桌面 GUI 中实现延迟加载?

PS:请注意,这是我第一次做多线程和 wxPython。我是 Python/Django 的早期 Web 开发人员。另外,由于限制,我无法共享代码。

4

3 回答 3

2

您应该重新设计您的应用程序,以便数据加载部分和数据显示部分是分开的。在一个单独的线程中加载数据,该线程应该在您的应用程序中填充数据库模型,使用该模型填充 GUI,因此当应用程序加载时,GUI 将快速加载,但会在数据没有的地方显示“正在加载...”或类似的东西尚未加载。

加快速度的另一种方法是在需要查询之前不要运行查询,例如在 get 查询 DB 上使用 get 方法将它们包装在一个类中,但所有这些都取决于上下文。

此外,如果 GUI 主要用于查看,那么您可以加载第一组小数据并将其他数据推送到用户必须通过某些菜单或选项卡的其他视图,这样您可以延迟加载直到需要它或加载它们在背景中。

于 2012-04-19T17:02:12.427 回答
0

有几种方法可以防止 GUI 挂起。当然,您可以执行多线程并将记录填充到全局字典中。但是您可能会遇到全局解释器锁(GIL),这可能无助于 GUI 的响应能力。

第一种选择是使用 GUI 工具包的事件驱动特性,并使用工具包提供的“超时”或“计时器”功能来调用一个函数,该函数每次调用时都会加载几条记录。生成器函数可以很好地解决这个问题。这可能是最容易实现的。一次可以加载多少条记录取决于机器的速度。我建议从一条记录开始,测量记录的加载,并增加记录的数量,这样每次调用的时间不会超过 0.1 秒。

第二是使用第二个进程加载数据,然后将其以小块的形式发送到 GUI。使用单独的进程(使用multiprocessing模块)具有不会遇到 Python 的 GIL 的优点。请注意,此方法或多或少包含第一种方法,因为您仍然必须在 GUI 的事件循环中处理来自第二个进程的消息。

于 2012-04-19T20:21:16.460 回答
0

您没有提到您使用哪些小部件将数据加载到其中,但如果您使用 wx.grid.Grid 或 ListCtrl,那么是的,在各个小部件的虚拟实现中存在一些“延迟”加载内容。例如,请参阅 wxPython 演示,了解可以容纳一百万个单元的网格。另请参阅 Anurag 的回答。您真的不需要一次加载所有数据。只需加载您可以实际显示的数据。然后您可以在用户滚动时加载更多内容(或在后台线程中预加载)。

于 2012-04-19T20:55:58.540 回答