python - PyQt:使用线程访问对象

标签 python multithreading queue pyqt

我目前正在开发 small markdown-editor ,但我有一个问题:

虽然速度非常快,但 Markdown 模块无法发挥魔力,而且由于每次更改时它都会处理整个文本,因此程序将变得无响应,例如按住退格键。

如何使用线程(子进程、QThread)来实现类似以下内容?

  1. 在处理过程中更改文本时,作业将被推送到队列中。如果队列已包含作业,则该作业将被新作业替换。
  2. 更改文本且队列中没有作业时,将执行新作业。
  3. 当作业完成时,队列中的作业将被执行。如果没有,我们就完成了。

澄清

我并不想要上面的算法,而是一种实现持续但不缓慢的渲染类型的方法。我想在“后台”触发渲染作业,但一次一个,确保始终执行最新的渲染作业。

  1. 用户开始更改文本。
  2. 当前文本的渲染作业在另一个线程中启动。
  3. 一旦完成并且渲染的 HTML 替换了旧的 HTML,就会确定是否仍然需要渲染,即刚刚渲染的是最新文本还是较旧的版本。
  4. 如果文本和渲染仍然不同步,请转到 2。

请注意,澄清上面的算法是实现此目的的一种方法,其中 3.(异步性的确定)被实现为 1-thread-queue。另请注意,只有最新的工作才真正需要完成,但我也希望完成随机的中间工作,以防止一次插入大量新输入的内容。

最佳情况:在快速、连续地输入大型文档时,渲染 View 每隔几个单词左右就会更新一次,而编辑器始终保持响应。

最佳答案

对我来说,这看起来像是 QThreadPoolQRunnable 的工作:

  • 创建一个派生自 QRunnable 的类,描述“渲染作业”
  • 创建一个 QThreadPool,并将 maxThreadCount 设置为 1(非常重要,因为一次只能有一个渲染线程)。
  • 每次文本更改时,创建“渲染作业”类的实例(可能启用了 autoDelete),并使用 QThreadPool.start() 将其添加到线程池QThreadPool 维护自己的待处理作业队列,因此,如果当前有另一个作业正在运行,新作业也不会丢失。在这种情况下,一旦当前作业完成,就会执行它。

要限制创建的渲染作业的数量,您不应直接在 .textChanged 信号上启 Action 业,而应通过 QTimer 间接启 Action 业。每次文本更改时,如果计时器实际发出 .timeout,则以 500 毫秒的超时时间重新启动计时器,并且仅启动新的“渲染作业”。

在实现“渲染作业”类时,请记住不要直接访问任何 GUI 类。相反,在“渲染作业”类中定义一个信号,渲染完成后,该信号以渲染的 HTML 字符串作为参数发出,并将其与显示小部件的 .setText() 连接。

这并不完全是您所要求的,因为正在运行的渲染作业永远不会中断,而是始终完成。因此,如果文本变化非常快(例如用户按住退格键),预览可能会在一定程度上不同步。但是,我认为这是解决您的问题的最简单、最直接的解决方案,因为它不需要锁定、同步或跟踪当前正在运行的作业。每个作业都以“即发即忘”的方式真正异步运行。

关于python - PyQt:使用线程访问对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6576831/

相关文章:

python - 接收时间过长如何关闭 session ?

python - 在 Django 模板中呈现列表

跨多个元素的 jQuery 动画队列

java - "AWT-EventQueue-0"java.lang.NullPointerException 异常

multithreading - 为什么对于每个线程来说,preempt_count是足够的

java - 如何更新然后选择更新的行

algorithm - 最短路径 - 广度优先搜索

python - 使用 scrapy 从 200k 域中提取文本

python - Sublime 布局分为 3 个面板,以创建自定义布局

java - 为什么 Char 不会打印,并且计数器超出了我的循环;