gpt4 book ai didi

python - 在 PyQt 中使用 QThread 的正确方法示例?

转载 作者:IT老高 更新时间:2023-10-28 22:05:46 27 4
gpt4 key购买 nike

我正在尝试学习如何在 PyQt Gui 应用程序中使用 QThreads。我有一些可以运行一段时间的东西,(通常)有可以更新 Gui 的点,但我想把主要工作分成自己的线程(有时东西会卡住,最终有一个很好的取消/重试按钮,如果 Gui 因为主循环被阻塞而被卡住,这显然不起作用)。

我已阅读 https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/ .该页面说重新实现 run 方法不是这样做的方法。我遇到的问题是找到一个 PyQt 示例,它有一个执行 Gui 的主线程和一个不这样做的工作线程。这篇博客文章是针对 C++ 的,所以虽然它的例子确实有帮助,但我还是有点迷茫。有人可以指出一个在 Python 中正确执行此操作的示例吗?

最佳答案

这是一个单独的工作线程的工作示例,它可以发送和接收信号以允许它与 GUI 通信。

我做了两个简单的按钮,一个在单独的线程中开始长时间计算,一个立即终止计算并重置工作线程。

在这里强制终止线程通常不是最好的处理方式,但在某些情况下,始终优雅退出不是一种选择。

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_())

关于python - 在 PyQt 中使用 QThread 的正确方法示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16879971/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com