我一直在研究关于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 _()
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
信号QThread
与threadFinished
相关联,依此类推。
一些非常粗糙的问题虽然我猜是一个复杂的问题:
- 为什么虽然正式文档声明调用QThread
的{{1}}函数是线程启动事件处理所必需的,但这似乎是在没有调用特定函数的情况下发生的
- 在某些情况下,线程终止由exec_()
捕获/处理,而在某些情况下则不会
- 最重要的是:为什么申请不会终止? (我也试过threadFinished
)
答案 0 :(得分:1)
只需在app.quit()
处理程序中调用threadFinished
即可,如果您有可见的小部件,hide()
和destroy()
主窗口,则应该注意销毁所有孩子。