簡體   English   中英

如何從正在運行的QThread發信號回到啟動它的PyQt Gui?

[英]How to signal from a running QThread back to the PyQt Gui that started it?

我試圖了解如何使用從Qthread返回到啟動的Gui接口的信令。

設置:我有一個需要幾乎無限期運行的進程(模擬)(或者至少在很長一段時間內運行)。當它運行時,它執行各種計算,並且一些結果必須被發送回GUI,將實時適當地顯示它們。 我正在使用PyQt進行GUI。 我最初嘗試使用python的線程模塊,然后在SO和其他地方閱讀了幾個帖子后切換到QThreads。

根據Qt博客上的這篇文章你做錯了 ,使用QThread的首選方法是創建一個QObject,然后將其移動到Qthread。 所以我在PyQt中跟隨了關於QThread的onBackground線程的建議“>這個問題並嘗試了一個簡單的測試應用程序(下面的代碼):它打開了一個簡單的GUI,讓你啟動后台進程,並且它發布了更新步驟值一個旋轉盒。

但它不起作用。 GUI永遠不會更新。 我究竟做錯了什么?

import time, sys
from PyQt4.QtCore  import *
from PyQt4.QtGui import * 

class SimulRunner(QObject):
    'Object managing the simulation'

    stepIncreased = pyqtSignal(int, name = 'stepIncreased')
    def __init__(self):
        super(SimulRunner, self).__init__()
        self._step = 0
        self._isRunning = True
        self._maxSteps = 20

    def longRunning(self):
        while self._step  < self._maxSteps  and self._isRunning == True:
            self._step += 1
            self.stepIncreased.emit(self._step)
            time.sleep(0.1)

    def stop(self):
        self._isRunning = False

class SimulationUi(QDialog):
    'PyQt interface'

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

        self.goButton = QPushButton('Go')
        self.stopButton = QPushButton('Stop')
        self.currentStep = QSpinBox()

        self.layout = QHBoxLayout()
        self.layout.addWidget(self.goButton)
        self.layout.addWidget(self.stopButton)
        self.layout.addWidget(self.currentStep)
        self.setLayout(self.layout)

        self.simulRunner = SimulRunner()
        self.simulThread = QThread()
        self.simulRunner.moveToThread(self.simulThread)
        self.simulRunner.stepIncreased.connect(self.currentStep.setValue)


        self.connect(self.stopButton, SIGNAL('clicked()'), self.simulRunner.stop)
        self.connect(self.goButton, SIGNAL('clicked()'), self.simulThread.start)
        self.connect(self.simulRunner,SIGNAL('stepIncreased'), self.currentStep.setValue)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    simul = SimulationUi()
    simul.show()
    sys.exit(app.exec_())

這里的問題很簡單:你的SimulRunner永遠不會被發送一個信號,導致它開始工作。 這樣做的一種方法是將它連接到Thread的started信號。

另外,在python中你應該使用新式的連接信號的方式:

...
self.simulRunner = SimulRunner()
self.simulThread = QThread()
self.simulRunner.moveToThread(self.simulThread)
self.simulRunner.stepIncreased.connect(self.currentStep.setValue)
self.stopButton.clicked.connect(self.simulRunner.stop)
self.goButton.clicked.connect(self.simulThread.start)
# start the execution loop with the thread:
self.simulThread.started.connect(self.simulRunner.longRunning)
...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM