QThread - 更改全局列表中的数据 - 不同的值

QThread - changing data in global list - different values

我正在使用 QThread 进行一些时间密集型计算以防止 GUI 冻结。在 QThread 中,我在线程生命周期内多次访问和更改全局列表,但是我无法获得与仅在主线程上相同的结果。

我假设您必须执行某种锁定,但我是 QThread 的新手,不知道如何实现它。

#Main Thread
                    self.runGasAnalysisThread = GasAnalysisThread()
                    self.runGasAnalysisThread.start()

#QThread
class GasAnalysisThread(QtCore.QThread):
    """Performs gas analysis function"""
    def __init__(self,parent = None):
        super().__init__(parent)

    def run(self):
        try:
            boolValue = True
            while True:
               #Change lists here
               float(Data.TestList[0])+ 1 #Data is another module I am using to store variables

同样,将代码移动到主线程可以正常工作,但是一旦我使用 QThread 执行此操作,我就会得到不同的结果。

我将如何实施锁定机制来防止这种情况发生?

在使用 Qt 的线程时经常会感到困惑,因为人们会认为子classing QThread 是正确的路径。
事实上,QThread 是 Qt 线程对象,您的进程实际上是 运行,这意味着您需要一个单独的 class 和 move 它实例 in 一个 QThread。 Subclassing QThread 通常是不必要的。
如果您需要在 "worker"(执行处理的对象)和主线程(如在 GUI 中)之间进行任何类型的交互,最好使用 Qt 的信号。

在这个例子中,我使用一个按钮来开始处理,一旦处理器启动它就会禁用该按钮,并且 re-enables 一旦它发出进程已完成的信号。

class Worker(QtCore.QObject):
    stateChanged = QtCore.pyqtSignal(bool)

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

    def run(self):
        self.stateChanged.emit(True)
        try:
            boolValue = True
            while True:
               # this doesn't make much sense, as it doesn't seem to do anything;
               # I'll leave it just for the sake of the argument
               float(Data.TestList[0]) + 1
        except:
            pass
        self.stateChanged.emit(False)

class SomeWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        layout = QtWidgets.QHBoxLayout()
        self.setLayout(layout)
        self.startButton = QtWidgets.QPushButton('Start')
        layout.addWidget(self.startButton)

        self.worker = Worker()
        self.workerThread = QtCore.QThread()
        self.worker.moveToThread(self.workerThread)
        self.workerThread.started.connect(self.worker.run)

        self.startButton.clicked.connect(self.workerThread.start)
        self.worker.stateChanged.connect(self.startButton.setDisabled)