Python+PyQT5的子线程更新UI界面的实例

yizhihongxing

Python+PyQT5多线程实现UI更新的原理和实现步骤:

为什么需要使用多线程进行UI更新

在 PyQT5 中,所有的UI操作都在主线程中执行,如果在主线程中进行耗时操作,就会导致UI界面的卡顿,甚至出现假死的情况,给用户的使用带来不好的体验。因此,我们需要在不阻塞UI界面的情况下,进行耗时操作,使用多线程的方式,将耗时操作放在子线程中执行。

实现步骤

  1. 创建线程类,在其中编写耗时操作。需要注意的是,在耗时操作执行完之后,需要通过信号(signal)告诉主线程需要更新UI。

示例代码:

from PyQt5.QtCore import QThread, pyqtSignal

class WorkThread(QThread):
    update_signal = pyqtSignal(str)

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

    def run(self):
        name = self.get_name()
        self.update_signal.emit(name)

    def get_name(self):
        # 模拟耗时操作
        import time
        time.sleep(3)

        return 'Jack'
  1. 在主线程中创建一个子线程对象,并连接子线程的信号和槽。

示例代码:

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.work_thread = WorkThread()
        self.work_thread.update_signal.connect(self.update_name_label)

    def update_name_label(self, name):
        self.ui.name_label.setText(name)
  1. 启动子线程。

示例代码:

self.work_thread.start()
  1. 在连接子线程信号和槽的函数中,更新UI。注意在更新UI时要使用QMetaObjectinvokeMethod方法,将更新UI的函数加入到主线程消息队列中,从而在主线程执行更新操作。

示例代码:

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # 省略部分代码

        self.move_button.clicked.connect(self.start_update_name_thread)
        self.work_thread.update_signal.connect(self.update_name_label)

    def start_update_name_thread(self):
        self.work_thread.start()

    def update_name_label(self, name):
        # 将更新label的函数加入到主线程的消息队列中,由主线程执行
        QMetaObject.invokeMethod(self.ui.name_label, 'setText', Qt.QueuedConnection, Q_ARG(str, name))

示例说明

示例一: 在子线程中执行一个函数,并将结果通过信号传递到主线程更新UI。

以下示例代码创建一个WorkThread线程类,其中的get_name函数模拟一个耗时操作,在其中休眠3秒,并返回一个字符串。当子线程执行完毕时,通过信号将获取到的字符串传递给主线程,在主线程中更新UI。

from PyQt5.QtCore import QThread, pyqtSignal, QMetaObject

class WorkThread(QThread):
    update_signal = pyqtSignal(str)

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

    def run(self):
        name = self.get_name()
        self.update_signal.emit(name)

    def get_name(self):
        # 模拟耗时操作
        import time
        time.sleep(3)

        return 'Jack'

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # 省略部分代码

        # 创建子线程对象
        self.work_thread = WorkThread()

        # 连接信号和槽
        self.work_thread.update_signal.connect(self.update_name_label)

    def start_update_name_thread(self):
        '''
        按钮点击事件,启动子线程
        '''
        self.work_thread.start()

    def update_name_label(self, name):
        '''
        更新UI函数
        '''
        # 将更新label的函数加入到主线程的消息队列中,由主线程执行
        QMetaObject.invokeMethod(self.ui.name_label, 'setText', Qt.QueuedConnection, Q_ARG(str, name))

示例二: 在子线程中执行多个函数,并将最终结果通过信号传递到主线程更新UI。

以下示例代码创建一个WorkThread线程类,其中的get_name函数模拟一个耗时操作,在其中休眠3秒,并返回一个字符串。当子线程执行完毕时,通过信号将获取到的字符串传递给主线程,在主线程中更新UI。

from PyQt5.QtCore import QThread, pyqtSignal, QMetaObject

class WorkThread(QThread):
    update_signal = pyqtSignal(str)

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

    def run(self):
        name = self.get_name()
        age = self.get_age()

        # 将结果组合成一个字符串
        result_str = f"姓名:{name};年龄:{age}"
        self.update_signal.emit(result_str)

    def get_name(self):
        # 模拟耗时操作
        import time
        time.sleep(3)

        return 'Jack'

    def get_age(self):
        # 模拟耗时操作
        import time
        time.sleep(2)

        return '18'

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # 省略部分代码

        # 创建子线程对象
        self.work_thread = WorkThread()

        # 连接信号和槽
        self.work_thread.update_signal.connect(self.update_info_label)

    def start_update_info_thread(self):
        '''
        按钮点击事件,启动子线程
        '''
        self.work_thread.start()

    def update_info_label(self, info):
        '''
        更新UI函数
        '''
        # 将更新label的函数加入到主线程的消息队列中,由主线程执行
        QMetaObject.invokeMethod(self.ui.info_label, 'setText', Qt.QueuedConnection, Q_ARG(str, info))

以上为Python+PyQT5的子线程更新UI界面的实例的详细讲解,希望能够帮到你。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python+PyQT5的子线程更新UI界面的实例 - Python技术站

(0)
上一篇 2023年6月13日
下一篇 2023年6月13日

相关文章

  • Django JSonResponse对象的实现

    下面是关于“Django JsonResponse对象的实现”的详细攻略: 什么是Django JsonResponse对象 在Django中,JsonResponse是一个HTTP响应对象,它会将传入的Python数据转换为JSON数据并返回到客户端。JSON表示JavaScript对象表示法(JavaScript Object Notation),它是一…

    python 2023年6月3日
    00
  • python解压TAR文件至指定文件夹的实例

    想要解压TAR文件至指定文件夹,需要使用Python标准库中的TarFile模块。具体步骤如下: 步骤一:导入TarFile模块 在Python中,我们使用import语句来导入需要使用的模块。因此,在开始解压TAR文件之前,需要在代码开头导入TarFile模块。 import tarfile 步骤二:打开TAR文件 使用TarFile模块中的open()函…

    python 2023年6月3日
    00
  • 利用一个简单的例子窥探CPython内核的运行机制

    这里提供一份完整的攻略,帮助你利用一个简单的例子窥探CPython内核的运行机制。 什么是CPython? CPython是一种常见的Python解释器,它是使用C语言编写的,是Python开发高性能应用程序的首选方案。在CPython中,Python代码先被解析,然后被转化成AST抽象语法树后再被编译成字节码,最后字节码被执行。 第一步:创建一个简单的Py…

    python 2023年5月31日
    00
  • for循环在Python中的工作原理详细

    下面我将详细讲解 for 循环在 Python 中的工作原理。 什么是 for 循环? for 循环是 Python 中最常用的一个循环结构,可以遍历任何序列,比如列表、元组、字符串等。for 循环的语法如下: for 变量 in 序列: 执行语句… 其中,“变量”表示每次循环中用来存储序列中的一个元素的变量名,“序列”可以是任何可迭代对象,比如列表、元…

    python 2023年5月14日
    00
  • Python对象的底层实现源码学习

    Python对象的底层实现源码学习攻略 Python对象的底层实现是Python编程语言中非常重要的一个知识点。通过深入学习Python对象的底层实现,可以帮助我们更好地理解Python的内部机制,从而编写更加高效、可靠的Python程序。 以下是Python对象的底层实现源码学习的完整攻略: 第一步:理解Python对象的基本特性 在深入学习Python对…

    python 2023年5月19日
    00
  • Python实战之天气预报系统的实现

    Python实战之天气预报系统的实现 天气预报系统是一个非常实用的应用程序,可以帮助我们了解未来几天的天气情况。本攻略将介绍如何使用Python编写一个简单的天气预报系统,包括如何获取天气数据、如何进行数据解析和展示等。 获取天气数据 我们可以使用Python的requests库来获取天气数据。以下是一个示例代码,用于获取北京市的天气数据: import r…

    python 2023年5月15日
    00
  • python实现抽奖小程序

    下面是Python实现抽奖小程序的完整攻略: 需求分析 在开始编写程序前,我们需要先明确需求。这个抽奖程序需要实现以下功能:1. 输入参与抽奖人员名单2. 从名单中随机选取若干个人作为获奖者3. 输出获奖者名单 方案设计 知道了需求,我们就可以开始设计实现方案了。为了实现这个抽奖小程序,我们可以采用以下方案:1. 通过Python内置的random模块实现随…

    python 2023年5月23日
    00
  • 基于Python实现对PDF文件的OCR识别

    我将为你详细讲解“基于Python实现对PDF文件的OCR识别”的完整攻略。 简介 OCR(Optical Character Recognition)即光学字符识别,是指将图像中的文字、数字等字符转换成可以被计算机识别的编码格式的过程。在实际应用中,PDF文件曾经难以被OCR识别,但随着技术的发展,现在很多开源的OCR工具支持对PDF文件的识别了。 本篇攻…

    python 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部