QThread - изменение данных в глобальном списке - разные значения - PullRequest
0 голосов
/ 08 июля 2019

Я использую QThread для выполнения интенсивных вычислений, чтобы избежать зависания графического интерфейса. В 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, я получаю другие результаты.

Как мне реализовать механизм блокировки, чтобы этого не происходило?

1 Ответ

0 голосов
/ 09 июля 2019

При использовании потоков Qt часто путают, так как можно подумать, что подкласс QThread будет правильным путем.
Правда в том, что QThread - это объект потока Qt, в котором фактически выполняется ваш процесс, а это значит, что вам потребуется отдельный класс для него и move его экземпляр в QThread. Подклассы 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)


...