我正在使用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进行操作,我就会得到不同的结果。
我将如何实现锁定机制以防止这种情况发生?
答案 0 :(得分:0)
使用Qt的线程时经常会感到困惑,因为人们会认为子类化QThread是正确的路径。
事实是,QThread是实际运行进程的Qt线程对象,这意味着您需要一个单独的类,并在QThread中将其 move 实例 。通常不需要对QThread进行子类化。
如果您需要“工人”(执行处理的对象)与主线程(如GUI中)之间的任何形式的交互,则使用Qt的信号是一种很好的做法。
在此示例中,我使用按钮来启动处理,一旦处理器启动,它将禁用该按钮,并在信号指示该过程完成后重新启用它。
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)