为什么与直接传递变量相反,为什么必须将类的实例传递给线程以修改其数据?

时间:2018-11-23 14:10:27

标签: python pyqt qthread

我正在创建一个用户界面,有些操作需要一些时间才能完成。

该过程获取一些数据。我想在Ui类中使用这些数据。

为防止接口冻结,我使用了一个worker对象,该对象放置在单独的线程中并使用信号进行控制。

要访问工作人员检索到的数据,我传递Ui对象,并让工作人员更新Ui类数据变量的内容。

如果我尝试直接传递var并在工作线程中对其进行修改,则Ui类中的内容不会更改。为什么会这样?

代码示例(有效):

from PyQt5 import QtCore
QtCore.Signal = QtCore.pyqtSignal

class threadController(QtCore.QObject):

    fire = QtCore.Signal()

    def __init__(self):
        super().__init__()

class worker(QtCore.QObject):

    finished = QtCore.Signal()

    def __init__(self,ob):
        super(worker,self).__init__()
        self.ob = ob

    def workerfunction(self):
        self.ob.var = [1,2,3] #modify the variable
        self.finished.emit()


class Ui():

    def __init__(self):
        self.thread1 = QtCore.QThread()
        self.thread1.start()
        self.var = [] #Create an empty variable
        self.workerobj = worker(self)
        self.workerobj.moveToThread(self.thread1)
        self.threadControllerObj = threadController()
        self.threadControllerObj.fire.connect(self.workerobj.workerfunction)

    def startThreadProcess(self):
        self.workerobj.finished.connect(self.check) #Need to make sure the thread has finished
        self.threadControllerObj.fire.emit() #fire the worker function


    def check(self):
        print(self.var) #this runs when the worker function in the thread has finished

if __name__ == '__main__':

    app = QtCore.QCoreApplication([])
    UiObj = Ui()
    UiObj.startThreadProcess()
    QtCore.QTimer.singleShot(1000, app.quit)
    app.exec_()

除此之外,这是否是访问在单独线程中运行的辅助函数中生成的数据的正确方法?

代码示例(这不起作用)

from PyQt5 import QtCore
QtCore.Signal = QtCore.pyqtSignal

class threadController(QtCore.QObject):

    fire = QtCore.Signal()

    def __init__(self):
        super().__init__()

class worker(QtCore.QObject):

    finished = QtCore.Signal()

    def __init__(self,var):
        super(worker,self).__init__()
        self.var = var

    def workerfunction(self):
        self.var = [1,2,3]
        self.finished.emit()


class container():

    def __init__(self):
        self.thread1 = QtCore.QThread()
        self.thread1.start()
        self.var = []
        self.workerobj = worker(self.var)
        self.workerobj.moveToThread(self.thread1)
        self.threadControllerObj = threadController()
        self.threadControllerObj.fire.connect(self.workerobj.workerfunction)

    def startThreadProcess(self):
        self.workerobj.finished.connect(self.check) #Need to make sure the thread has finished
        self.threadControllerObj.fire.emit() #fire the worker function


    def check(self):
        print(self.var) #this runs when the worker function in the thread has finished

if __name__ == '__main__':

    app = QtCore.QCoreApplication([])
    contain = container()
    contain.startThreadProcess()
    QtCore.QTimer.singleShot(1000, app.quit)
    app.exec_()

0 个答案:

没有答案