Как использовать библиотеку Python PyQt для управления потоками
PyQt предоставляет надежную среду для создания графических пользовательских интерфейсов в приложениях Python. Чтобы обеспечить плавное и быстрое обновление пользовательского интерфейса при выполнении фоновых задач, Qt использует потоки, которые выполняются одновременно с основным потоком графического интерфейса. Однако эффективное использование потоков требует тщательного рассмотрения.
Как указано в статье Майи Пош, повторная реализация метода run не должна быть предпочтительным подходом при работе с QThreads. Вместо этого рассмотрите возможность использования сигналов и слотов для облегчения связи между потоками. Для иллюстрации правильной реализации будет представлен практический пример.
Пример управления потоками PyQt
В примере мы создаем отдельный рабочий поток, который обрабатывает длинные вычисления в то время как основной поток графического интерфейса управляет графическим интерфейсом. Рабочий поток передает обновления статуса в графический интерфейс через сигналы.
Чтобы начать расчет, пользователь нажимает кнопку «Пуск». Кнопка «Отмена» может использоваться для прекращения операции и сброса рабочего потока. Обратите внимание, что принудительное завершение потока обычно не рекомендуется, а используется в демонстрационных целях.
Код 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 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_())
Этот пример демонстрирует правильное использование QThreads в приложении PyQt, позволяющее эффективно выполнять фоновые операции без зависания пользовательского интерфейса.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3