PySide:QThread事件处理

时间:2013-09-10 15:43:56

标签: python pyside qthread

我一直在研究关于PySide线程的以下问题,但我发现文档很少,所以这里有一篇关于我的发现的长篇文章,希望得到一些关于它如何发展的简明反馈。 假设我们正在构建一个调用某些linux进程的多线程GUI应用程序。 我们将使用QThread类从内部调用QProcess,目的是让应用程序在准备就绪时同时运行多个进程(在不同的线程中)

我只使用QThread类并从QApplication主循环开始

案例1 : - 我们将线程终止信号连接到调用self.exit的同一个类的另一个函数(以便线程类退出) - 没有按照PySide官方文档http://tinyurl.com/qh7cooa

的说明调用self.exec_()
#!/usr/bin/python3.2
from PySide import QtGui
from PySide import QtCore
import sys, random

class ProcThread(QtCore.QThread):

    def __init__(self, parent=None):
        super(ProcThread, self).__init__(parent)

    def run(self):
        try:
            self.qproc = QtCore.QProcess()
            self.finished.connect(self.threadFinished)
            filename = "/home/user1/Desktop/fileno"+str(random.randint(1, 10000))+".txt"
            self.qproc.start("touch", [filename])       
        except Exception as error:
            print(str(error))
            raise(error)

    #self.exec_()

    def threadFinished(self):
        print("Thread has finished")
        self.qproc.close()

app = QtGui.QApplication(sys.argv) 
procthread = ProcThread()
procthread.start()
app.exec_()

结果:捕获线程终止(消息“线程已完成”被打印),进程运行(文件已创建)但应用程序未退出

案例2 :与之前相同,但现在也调用self._exec()(取消注释前面代码段中的相关行) 结果:未捕获线程终止,进程确实运行(文件已创建),并且在Ctrl + Z /必须明确终止后,应用程序再次不退出(仍作为后台作业)

案例3 :现在连接QProcess终止self.qproc.finished.connect(self.threadFinished)时发出的信号。 没有调用self.exec _()

只引用try-except之间的代码 - #self.exec_()仍然被评论
self.qproc = QtCore.QProcess()
self.qproc.finished.connect(self.threadFinished)
filename = "/home/pantelis/Desktop/fileno" + str(random.randint(1, 10000)) + ".txt"
self.qproc.start("touch", [filename])

RESULT :与案例2中一样 - 未捕获线程终止,进程确实运行(文件已创建),应用程序再次不会退出

案例4 :与案例1中一样,但现在在threadFinished中添加以下行 self.exit() 结果:与案例2中一样 - 未捕获线程终止,进程确实运行(文件已创建),应用程序再次不会退出

案例5 :与案例4一样,只需取消注释self.exec_() 结果:线程终止是CAUGHT(消息“线程已完成”被打印),文件IS已创建,应用程序再次不会退出

案例6,7,8 :在self.qproc.close() / self.qproc.terminate() / self.qproc.kill()中添加threadFinished以明确终止特定功能的QProcess 结果:与案例5中一样

还可以尝试不同的替代方案,例如将self.terminated信号QThreadthreadFinished相关联,依此类推。 一些非常粗糙的问题虽然我猜是一个复杂的问题: - 为什么虽然正式文档声明调用QThread的{​​{1}}函数是线程启动事件处理所必需的,但这似乎是在没有调用特定函数的情况下发生的 - 在某些情况下,线程终止由exec_()捕获/处理,而在某些情况下则不会 - 最重要的是:为什么申请不会终止? (我也试过threadFinished

1 个答案:

答案 0 :(得分:1)

只需在app.quit()处理程序中调用threadFinished即可,如果您有可见的小部件,hide()destroy()主窗口,则应该注意销毁所有孩子。