【问题标题】:Cannot terminate PyQT QThread无法终止 PyQT QThread
【发布时间】:2015-09-08 20:46:36
【问题描述】:

这个问题和我的previous one有关

问题发生在我在Alpha to Gamma 项目之间切换的速度太快。 run()GenericThread 方法无法在没有错误的情况下完成它的循环,因为当我在 List1 的项目之间切换时,给它的信息会发生变化

我添加了exeptions,但这不是在这种情况下最好的解决方法,如果线程正在运行,我必须终止它然后重新启动它,但是当我终止它时,GUI 会永远冻结(但它不是喜欢它在项目之间切换时一直冻结,有时 self.terminate() 有时不起作用并且冻结我不知道为什么)...

class GenericThread(QtCore.QThread):
    def __init__(self, parent=None):
        QtCore.QThread.__init__(self, parent)

    def stop(self):
        self.terminate()

    def __del__(self):
        self.quit()
        self.wait()

    def run(self):
        #Some very long stuff
        self.emit( QtCore.SIGNAL('itemSelectionChanged()'))
        return

class MainUI(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self)
        self.ui = Ui_Win()
        self.ui.setupUi(self)

        self.genericThread = GenericThread(self, listIndex=2)
        self.connect(self.genericThread, QtCore.SIGNAL("fillListWithItems(QString, int)"), self.fillListWithItems )
        self.ui.List1.list1SelectedItem.connect(self.fill_List2)
        ...

    def fill_List2(self):
        if self.genericThread.isRunning():
            self.genericThread.stop()
        self.ui.List2.clear()
        list1SelectedItem = str(self.ui.List1.currentItem().text())
        self.genericThread.start()

现在,为什么 GUI 冻结以及如何正确终止 self.genericThread

【问题讨论】:

  • 如果在再次调用 start 之前重新实例化 self.genericThread 是否仍然会崩溃?
  • @three_pineapples 刚刚对其进行了测试,是的,它仍然崩溃
  • 你必须在'stop()'之后调用'wait()',终止函数不是立即的
  • @mguijarr wait() 将等待run() 返回一个值,该值仅在该长函数完成时才会导致,我不想等待这么久,因此它变得无用。
  • 对不起,不是真的:在调用“terminate()”之后,线程被“杀死”,但是你必须等待它真正停止,这取决于操作系统调度;你试过我的建议了吗?

标签: python multithreading qt pyqt qthread


【解决方案1】:

根据您的 cmets、@ekhumoro 和 @Pavel,我已经解决了我的问题,现在它可以按我的意愿运行,即使 self.terminate() 能正常工作会好得多。

class GenericThread(QtCore.QThread):
    def __init__(self, parent=None):
        QtCore.QThread.__init__(self, parent)
        self.stopFlag = False

    def stop(self):
        self.stopFlag = True

    def __del__(self):
        self.quit()
        self.wait()

    def run(self):
        #Some very long stuff
            if self.stopFlag:
                self.stopFlag = False #Resetting the flag (in my case I have to do this!)
                break #Breaks main loop to finish 'run()'
            else:
                self.emit( QtCore.SIGNAL('itemSelectionChanged()'))

class MainUI(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self)
        self.ui = Ui_Win()
        self.ui.setupUi(self)

        self.genericThread = GenericThread(self, listIndex=2)
        self.connect(self.genericThread, QtCore.SIGNAL("fillListWithItems(QString, int)"), self.fillListWithItems )
        self.ui.List1.list1SelectedItem.connect(self.fill_List2)
        ...

    def fill_List2(self):
        if self.genericThread.isRunning():
            self.genericThread.stop()
        self.ui.List2.clear()
        list1SelectedItem = str(self.ui.List1.currentItem().text())
        self.genericThread.start()

【讨论】:

    猜你喜欢
    • 2021-10-25
    • 1970-01-01
    • 1970-01-01
    • 2010-12-26
    • 1970-01-01
    • 2013-11-10
    • 1970-01-01
    • 2019-10-05
    • 1970-01-01
    相关资源
    最近更新 更多