当前位置: 首页 > 面试题库 >

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

冯和硕
2023-03-14
问题内容

我正在尝试学习如何在PyQt
Gui应用程序中使用QThreads。我有一些可以运行一段时间的东西,(通常)可以在其中更新Gui的点,但是我想将主要工作拆分为自己的线程(有时东西会卡住,最终有一个取消/重试按钮,如果Gui被冻结(因为主html" target="_blank">循环被阻塞),则该按钮显然不起作用)。

我已阅读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_())


 类似资料:
  • 问题内容: 我读了这篇文章《如何真正地,真正地使用QThreads》。完整说明,它说而不是子类qthread和重新实现run(),应使用moveToThread(QThread *)使用moveToThread将QObject推送到QThread实例上 这是C ++示例,但我不知道如何将其转换为python代码。 我一直在使用这种方法来生成qthread,但是如您所见,它使用的是不推荐的方式。我如

  • 本文向大家介绍PyQt 线程类 QThread使用详解,包括了PyQt 线程类 QThread使用详解的使用技巧和注意事项,需要的朋友参考一下 PyQt中的线程类 QtCore.QThread ,使用时继承QThread类 启动界面的线程暂称为UI线程。界面执行命令时都在自己的UI线程中。 如果在UI线程中执行网络连接和数据库操作等耗时的操作,界面会被卡住,Windows下有可能会出现“无响应”的

  • 问题内容: 我正在阅读有关PyQt5的一些文档,以提出一种简单的信号插槽机制。由于设计方面的考虑,我停了下来。 考虑以下代码: 为了跟踪对滑块所做的更改,我仅打印并记录所做的更改。我对代码不满意的是,我需要调用三次插槽以将相同的信息发送到3个不同的插槽。 是否可以创建自己的将整数发送到单个插槽的函数。插槽功能又会发出需要进行的更改吗? 也许我不完全了解它的目的,因为在PyQt Signal-Slo

  • 问题内容: 我刚刚在我的项目中发现了一些这样的sql查询构建: 这是否达到其目标,即减少内存使用量? 我对此表示怀疑,因为在构造函数中使用了“ +”(字符串concat运算符)。像下面的代码那样,将占用与使用String相同的内存量吗?我了解,使用时有所不同。 两条语句的内存使用量是否相等?请澄清。 提前致谢! 编辑: 顺便说一句, 这不是我的代码 。在一个旧项目中发现它。而且,查询的大小不如我的

  • 问题内容: 我有一个程序,可以通过我在PyQt中编写的gui与正在使用的无线电接口。显然,无线电的主要功能之一是传输数据,但要连续进行,我必须循环写入,这会导致gui挂起。由于我从未处理过线程,因此我尝试使用.“无线电”需要在两次传输之间睡眠的方法来消除这些挂起,因此gui仍根据这些睡眠持续的时间来挂起。 是否有使用QThread修复此问题的简单方法?我一直在寻找有关如何使用PyQt实现多线程的教

  • 本文向大家介绍Linux中Homebrew的正确使用方法,包括了Linux中Homebrew的正确使用方法的使用技巧和注意事项,需要的朋友参考一下 很多人都在使用Linux Homebrew ,有三个技巧可以帮助你更好的使用它: 避免环境污染 首先要避免将 Homebrew 的 bin 目录添加到 $PATH ,而仅仅将你需要使用的几个可执行做软连接放到 ~/bin 下面(这个目录在 $PATH