1

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

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

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

#!/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])

结果:如案例 2 - 未捕获线程终止,进程运行(创建文件)并且再次应用程序不退出

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

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

案例 6、7、8:添加self.qproc.close() / self.qproc.terminate() / self.qproc.kill()threadFinished从特定函数显式终止 QProcess 结果:如案例 5

也可以尝试不同的替代方案,例如链接to的self.terminated信号等。一些非常粗略的问题,尽管我猜这是一个复杂的问题:-为什么尽管正式文档指出调用's函数对于线程开始事件处理是必要的,但这似乎是在没有调用特定函数的情况下发生的-在某些情况下线程终止被捕获/处理,在某些情况下它不是 - 最重要的是:为什么应用程序不终止?(我也试过)QThreadthreadFinishedQThreadexec_()threadFinishedapp = QtCore.QCoreApplication(sys.argv)

4

1 回答 1

1

只需调用app.quit()您的threadFinished处理程序,如果您有可见的小部件hide()destroy()主窗口,这应该负责销毁所有子窗口。

于 2013-10-02T18:54:27.777 回答