如何利用Python 的PyQt 函式庫來管理執行緒
PyQt 為在Python 應用程式中建立圖形使用者介面提供了一個強大的框架。為了確保執行後台任務時 UI 更新流暢且反應靈敏,Qt 利用與主 GUI 執行緒同時執行的執行緒。然而,有效地使用線程需要仔細考慮。
如 Maya Posch 的文章所述,重新實作 run 方法不應成為使用 QThreads 時的首選方法。相反,請考慮使用訊號和插槽來促進線程之間的通訊。為了說明正確的實現,將提供一個實際範例。
PyQt 執行緒管理範例
在範例中,我們建立一個單獨的工作執行緒來處理長運算而主 GUI 執行緒則管理圖形介面。工作執行緒透過訊號將狀態更新傳達給 GUI。
要開始計算,使用者點選「開始」按鈕。 “取消”按鈕可用於終止操作並重設工作執行緒。請注意,通常不建議強制終止線程,但用於演示目的。
Python 程式碼
<code class="python">from PyQt4 import QtGui, QtCore import sys import random class Example(QtCore.QObject): signalStatus = QtCore.pyqtSignal(str) def __init__(self, parent=None): super(self.__class__, self).__init__(parent) # Create a gui object. self.gui = Window() # Create a new worker thread. self.createWorkerThread() # Make any cross object connections. self._connectSignals() self.gui.show() def _connectSignals(self): self.gui.button_cancel.clicked.connect(self.forceWorkerReset) self.signalStatus.connect(self.gui.updateStatus) self.parent().aboutToQuit.connect(self.forceWorkerQuit) def createWorkerThread(self): # Setup the worker object and the worker_thread. self.worker = WorkerObject() self.worker_thread = QtCore.QThread() self.worker.moveToThread(self.worker_thread) self.worker_thread.start() # Connect any worker signals self.worker.signalStatus.connect(self.gui.updateStatus) self.gui.button_start.clicked.connect(self.worker.startWork) def forceWorkerReset(self): if self.worker_thread.isRunning(): print('Terminating thread.') self.worker_thread.terminate() print('Waiting for thread termination.') self.worker_thread.wait() self.signalStatus.emit('Idle.') print('building new working object.') self.createWorkerThread() def forceWorkerQuit(self): if self.worker_thread.isRunning(): self.worker_thread.terminate() self.worker_thread.wait() class WorkerObject(QtCore.QObject): signalStatus = QtCore.pyqtSignal(str) def __init__(self, parent=None): super(self.__class__, self).__init__(parent) @QtCore.pyqtSlot() def startWork(self): for ii in range(7): number = random.randint(0,5000**ii) self.signalStatus.emit('Iteration: {}, Factoring: {}'.format(ii, number)) factors = self.primeFactors(number) print('Number: ', number, 'Factors: ', factors) self.signalStatus.emit('Idle.') def primeFactors(self, n): i = 2 factors = [] while i * i <= n: if n % i: i += 1 else: n //= i factors.append(i) if n > 1: factors.append(n) return factors class Window(QtGui.QWidget): def __init__(self): QtGui.QWidget.__init__(self) self.button_start = QtGui.QPushButton('Start', self) self.button_cancel = QtGui.QPushButton('Cancel', self) self.label_status = QtGui.QLabel('', self) layout = QtGui.QVBoxLayout(self) layout.addWidget(self.button_start) layout.addWidget(self.button_cancel) layout.addWidget(self.label_status) self.setFixedSize(400, 200) @QtCore.pyqtSlot(str) def updateStatus(self, status): self.label_status.setText(status) if __name__=='__main__': app = QtGui.QApplication(sys.argv) example = Example(app) sys.exit(app.exec_())</code>
此範例示範了 QThreads 在PyQt 應用程序,允許高效的後台操作,而不會凍結使用者介面。
以上是如何有效管理 PyQt 應用程式中的執行緒?的詳細內容。更多資訊請關注PHP中文網其他相關文章!