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

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日

相关文章

  • python从sqlite读取并显示数据的方法

    下面是详细讲解 “Python从SQLite读取并显示数据的方法” 的完整攻略: 步骤一:导入必要的库 在Python中,我们需要使用 sqlite3 库来管理SQLite数据库,同时还需要使用 pandas 库用于数据处理和表格显示。因此可以通过以下代码导入这两个库: import sqlite3 import pandas as pd 步骤二:连接SQL…

    python 2023年6月3日
    00
  • Python如何处理大数据?3个技巧效率提升攻略(推荐)

    那就让我来详细讲解一下“Python如何处理大数据?3个技巧效率提升攻略(推荐)”的完整攻略,包含以下三个技巧: 技巧一:使用适当的数据结构 在处理大量数据时,数据结构的选择非常重要。Python 中的列表、元组、集合以及字典等都是常见的数据结构,但它们的性能各不相同。在数据量比较大的情况下,应该选择性能更好的数据结构来存储和处理数据,比如使用 Numpy …

    python 2023年5月13日
    00
  • nx.adjacency_matrix计算邻接矩阵与真实结果不一致的解决

    在使用 nx.adjacency_matrix 函数计算邻接矩阵时,有时候会出现计算结果与预期不一致的情况,这可能是由于以下原因造成的:节点的排序可能会影响计算结果、网络图中存在对称边或自环等。本文将介绍如何解决这些问题。 问题一:节点排序对计算结果的影响 考虑以下简单的网络图: import networkx as nx G = nx.Graph() G.…

    python 2023年6月3日
    00
  • python实现五子棋算法

    下面是关于“Python实现五子棋算法”的完整攻略。 1. 五子棋算法简介 五子棋是一种双人对弈的纯策略型棋类游戏,通常在15×15的棋盘上进行。子棋的目标是在棋盘上先形成一条连续的、由相同颜色的棋子组成的直线,即五子连,获得胜利。 2. Python实现五子棋算法 2.1 算法流程 五子棋算法的流程如下: 初始化棋盘,括棋盘大小、棋子颜色等。 玩家落子,即…

    python 2023年5月13日
    00
  • Python用摘要算法生成token及检验token的示例代码

    首先,我们需要了解什么是摘要算法以及什么是Token。摘要算法是一种将任意长度的数据映射为固定长度摘要值的算法,通常用于数据完整性校验和数字签名等场景。而Token可以理解为一种加密过的字符串,里面包含了一定的信息,如用户ID、角色等,用于验证用户身份和权限。 生成Token的基本流程是将需要加密的信息先进行摘要算法哈希处理,再将哈希值与一定的盐进行混淆加密…

    python 2023年6月3日
    00
  • Python下载指定页面上图片的方法

    以下是 Python 下载指定页面上图片的方法的完整攻略: 背景 在某些情况下,我们需要将网页上的图片下载到本地进行保存或处理。此时,我们可以使用 Python 来实现这一功能。 方法 Python 中有多种方式可以下载网页上的图片,常见的有以下两种方法: 方法一:使用 requests 库下载图片 import requests # 定义要下载图片的 UR…

    python 2023年6月3日
    00
  • Python 中如何写注释

    当我们编写代码时,为了让其他人易于理解和阅读代码,或者为了让自己方便回忆代码的用途和思路,我们需要在代码中添加注释。在 Python 中,注释用 # 符号表示,可以有单行注释和多行注释两种方式。 单行注释 单行注释是用来解释一行代码的作用,其语法为在代码后面添加 # 符号。例如: a = 1 # 定义变量a并赋值为1 在这个例子中,定义了一个变量 a 并将其…

    python 2023年5月19日
    00
  • Python过滤序列元素的方法

    在Python中,我们可以使用不同的方法来过滤序列元素。本文将详细介绍Python中过滤序列元素的方法。 使用列表推导式过滤序列元素 列表推导式是一种简洁的语法,可以用于创建新的列表。我们可以在列表推导式中使用if语句来过滤序列元素。 以下是一个示例: numbers = [1, 2, 3, 4, 5, 6] even_numbers = [x for x …

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