在PyQt中取消后台任务

时间:2015-07-04 22:25:14

标签: python multithreading pyqt kill qthread

这个问题与this one非常相关,QThread没有解决方案,但它并不完全相同。

我想问一下是否有办法在PyQt中启动后台任务,并且可以通过按下按钮来kill

我的问题是我有一个用户界面和一些需要一段时间才能计算的外部(第三方)功能。为了在计算任务时不冻结用户界面,我使用QThread在后​​台运行它们,并在完成使用signals时同步UI。

但是,我想为外部用户添加选项以按下按钮并取消当前任务(因为不再需要/期望任务)。

对我而言,有些东西看起来像linux中的kill -9 *task*一样简单,在Qt中很难获得。

现在我使用以下形式的自定义Qthread:

mythread = Mythread()
mythread.finished.connect(mycallback)
mythread.start()

Mythread继承{{3}}覆盖run方法的位置。

在用户界面中,有一个按钮试图通过使用:

来杀死该线程
mythread.exit(0)
mythread.quit()
mythread.terminate()

它们都不起作用......我知道文档说明terminate方法确实有奇怪的行为......

所以问题是......我面对这个问题错了吗?如何杀死QThread?如果不可能,还有其他替代方案吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

尝试按照建议的方式杀死一个线程是一个非常常见的错误。

出于某种原因,很多人都没有意识到需要停止长期运行的任务 - 而不是线程。您将任务放在线程中,因为它阻止了GUI。但是这种情况并没有神奇地改变,因为你把它移到了另一个线程。它将以完全相同的方式阻止 线程,除非你做了什么来阻止它。一旦你停止它,线程就可以正常完成(即它的run()方法将退出)。

控制长时间运行任务的常用方法是通过一个简单的标志:

class Thread(QThread):
    def stop(self):
        self._flag = False

    def run(self):
        self._flag = True
        for item in get_items():
            process_item(item)
            if not self._flag:
                break
        else:
            self._flag = False