PyQt中的多线程QThread示例

2023-11-05

一、PyQt中的多线程

传统的图形用户界面应用程序都只有一个执行线程,并且一次只执行一个操作。如果用户从用户界面中调用一个比较耗时的操作,那么当执行这个程序时,虽然实际上该操作正在进行,但用户界面通常会冻结而不再响应。

为了解决这个问题,通常会让用户的UI界面运行在它自己的线程中,而另外的事件处理过程则发生在一个或多个其他线程中。这样做之后,即使在处理那些数据密集的事件时,应用程序也能对GUI用户界面保持响应。当在一个单处理器上运行时,多线程应用程序可能会比实现同样功能的单线程应用程序运行得更慢一些,无法体现出其优势。但在目前多处理器系统越来越普及的情况下,多线程应用程序可以在不同的处理器中同时执行多个线程,从而获得更好的总体性能。

二、创建线程

2.1 设计ui界面

我们通过下面这个小例子来展示一下多线程的处理。用户界面如下。

使用Qt designer新建一个widget窗口,然后在其中添加2个button,分别是theradA和threadB,点击btn_theradA时,会不断地在控制台打印字母A,点击btn_theradB打印字母B。保存该ui文件为Form.ui

20221208001038

界面设计完毕后,使用以下命令,将Form.ui转换为form.py

pyuic5 -o form.py Form.ui

20221208001747

2.2 设计工作线程

添加一个工作线程类,用于完成按钮按下后需要执行的任务。
MyThread.py

from PyQt5.QtCore import QThread, qDebug
import time

class MyThread(QThread):
    def __init__(self, thread_name):
        super().__init__()
        self.__stop_running = False         # 此变量用于控制线程的运行
        self.__thread_name = thread_name    # 线程名,用于区分是哪个线程

    def run(self):
        while not self.__stop_running:
            qDebug(f'{self.__thread_name} is running')  # 不停地打印,模拟执行任务
            time.sleep(1)
            
    def stop(self):
        self.__stop_running = True

在QT应用程序中提供多线程是非常简单的,只需要子类化QThread并且重新实现它的run()函数即可。

如上所述,我们定义了一个自己的Thread类,名为MyThread,它派生自QThread类,并且重新实现了run()函数。

当调用线程的start()函数时,就会自动调用run()函数。只要stop_running标志为false,run()函数就会不断地进行打印,模拟任务的执行。当控制离开run()函数时,线程就会终止。

2.3 主程序设计

程序入口文件main.py

from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QCloseEvent
from PyQt5.QtCore import qDebug
import sys
from MyThread import MyThread
from form import Ui_Form

class MyWidget(QWidget):
    def __init__(self) -> None:
        super().__init__()
        self.__init_ui()
        
        # 定义2个工作线程
        self.__threadA = MyThread('threadA')
        self.__threadB = MyThread('threadB')
        
        # 连接button的clicked信号到对应的槽函数
        self.__my_form.btn_threadA.clicked.connect(self.start_or_stop_threadA)
        self.__my_form.btn_threadB.clicked.connect(self.start_or_stop_threadB)
        
    def __init_ui(self):
        self.__my_form = Ui_Form()
        self.__my_form.setupUi(self)
        
    def start_or_stop_threadA(self):
        if self.__threadA.isRunning():
            self.__threadA.stop()
        else:
            self.__threadA.start()
        
    def start_or_stop_threadB(self):
        if self.__threadB.isRunning():
            self.__threadB.stop()
        else:
            self.__threadB.start()
            
    def closeEvent(self, e:QCloseEvent):
        qDebug('stop all threads...')
        self.__threadA.stop()
        self.__threadB.stop()
        self.__threadA.wait()
        self.__threadB.wait()
        e.accept()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    my_widget = MyWidget()
    my_widget.show()
    sys.exit(app.exec_())

主程序界面通过Ui_Form类的setupUi建立,随后我们将两个button的clicked信号绑定到我们定义的槽函数start_or_stop_threadA和start_or_stop_threadB上,这样,点击按钮之后,就可以执行我们自定义的线程动作。

在关闭窗口时,会产生QCloseEvent事件,我们重写了closeEvent方法来对线程执行了清理工作,确保应用程序是以一种原始清空的状态进行退出。当然了,在这个例子中,是否这样做其实并没有什么影响,这里只是举个例子示范一下。

三、运行结果示例

执行main.py, 单击按钮A时,控制台就会输出A,再次单击则会停止输出。按钮B同理。当按钮A和按钮B被按下同时工作时,A和B会交替输出。

运行效果如下:

20221208003621

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PyQt中的多线程QThread示例 的相关文章

随机推荐

  • C++11 map实现插入后按value自动排序

    本质上还是使用了map自动按照key进行排序的原理 所以将value放入key中可实现按value排序 include
  • 简单记录vue下单元测试及Mock数据

    1 vue cli 创建一个demo 创建一个 demo vue create demo 在VUE CLI 是有提供测试插件的 所以在构建项目时选择一个测试框架 运行测试脚本 在package json 中可以看到运行测试脚本命令 npm
  • 倾心倾力之作《Qt 5.9 C++开发指南》

    五一假期前收到了人民邮电出版社寄来的书 我们写的 Qt 5 9 C 开发指南 终于印刷出来了 从2016年11月开始写书 到今天终于印刷出版 历时约一年半 现在它终于面世了 成书过程 由于做项目的需要 在2014年开始转而用Qt编写软件 在
  • 301与302区别

    301与302区别 定义如下 301 Moved Permanently 被请求的资源已永久移动到新位置 并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一 如果可能 拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器
  • springboot多模块开发中实现打包

    前言 因为我使用的是idea社区版 所以在创建项目的时候他没有springboot的选项 所以只能创建普通maven项目 创建完成查看项目结构和pom文件 这里我并没有觉得有什么不对劲 所以没管 就去搭建其他模块了 这里就不展示了 后来我需
  • python函数与Lambda表达式

    python函数与Lambda表达式 函数的定义 def functionname parameters 函数 文档字符串 function suite return expression 函数定义的参数为形参 表示表示占据一个参数位置 传
  • Sql Server查询语句

    文章目录 Sql Server查询语句 基础查询 条件查询 模糊查询 Sql Server查询语句 对于Sql Server创建的表中的数据进行查询 可以进行 基础查询 条件查询 模糊查询 基础查询 基础查询语句为 select from
  • 央行数字货币研究所、中国信通院合作立项2项区块链国际标准

    国际电信联盟第十六研究组 简称ITU T SG16 于2021年4月19日至2021年4月30日召开全体会议 来自中国 美国 德国 巴西 西班牙 俄罗斯 瑞士 加拿大 英国 韩国 日本等国家和世界卫生组织等国际组织的百余名代表参加了此次为期
  • spring三级缓存总结

    前言 其实说到spring的三级缓存 也是经常被提到 自己也看过对应的源码 但是 总觉得自己还是没有真正的理解 为什么这样说呢 因为每次看到三级缓存相关的技术问题 自己心里感觉还是迷糊的 不知道为什么要有三级缓存 一级缓存不行吗 二级缓存是
  • unity3d学习笔记-动画(2.控制动画与Animator Controller)

    一 探索Animator Controller动画控制器 每当为选定的游戏对象创建第一个动画剪辑时 就会自动创建动画器组件 Animator负责分配动画 但是 它不控制实际的动画剪辑 这个任务落到了动画控制器身上 它也是用第一个动画剪辑自动
  • $.ajax如何在response中获取请求头

    ajax如何在response中获取请求头 下载文件时需要获取后端带在responseHeader中的文件名称 ajax type get url http xxxx currentuser contentType application
  • Qt操作excel的三方库Qtxlsx在Windows下使用注意事项

    Qt操作excel的三方库Qtxlsx在Windows下使用注意事项 文章目录 Qt操作excel的三方库Qtxlsx在Windows下使用注意事项 1 Qt Xlsx简介 2 编译及添加模块 2 1 下载及编译 2 2 拷贝相关文件集成到
  • WebGL 杂记

    WebGL 2D RotationHow to rotate in 2Dhttps webglfundamentals org webgl lessons webgl 2d rotation html 假设您有一个矩形 并且想要旋转它 在开
  • java 删除文件路径下的指定文件

    起因 租赁项目过期或未按指定机器被套用 检测到违反规定 需要删除数据库并删除重要文件 本文主要解决问题 删除文件夹下的指定文件 解决方案 import java io File public class TestMain public st
  • 水星迷你无线路由器ap模式 下要不要启用 dhcp服务器,水星(Mercury)Mini无线路由器AP模式设置...

    本文介绍了水星 MERCURY Mini系列无线路由器AP模式的设置方法 水星迷你路由器实现了即插即用 非常适合出差或者在旅行途中入住酒店时使用 直接把酒店房间里面的网线插在水星迷你无线路由器上 就可以正常使用了 下面以水星MW150RM迷
  • 编程 打油诗_CNC操机10年老员工献给大家的一首心酸打油诗

    操机苦 倒班累 操机倒班活受罪 半夜起 早晨睡 好比参加革命游击队 整日在思 彻夜不能寐 工作不顺奖金全作废 煎熬一夜 下班打瞌睡 吃个早餐凌晨还得排队 洗漱列队 厕所抢位 回到宿舍心神疲惫 请假难请 扣钱双倍 每天都在请假排队 数控操机何
  • Android之使用本地缓存数据

    前言 在通常做项目的时候 需要存储数据 会使用GreenDAO数据库 bmob后端云 或者其他方法 以及本篇文章所讲解的本地缓存 也就是通过SharedPreferences 来进行缓存 第一部分 1 那么首先呢需要创建一个缓存数据的类Ca
  • python编程中的注意事项

    虚拟环境 win下的虚拟环境创建 virtualenv name python 3 7 9 conda创建虚拟环境 conda create prefix home coData venv python 3 8 conda环境恢复 起因 c
  • 我的128创作纪念日

    机缘 写CSDN博客的时候 应该纯属一个巧合 还记得当初是和一个班上的同学一起记录学习笔记 最初是在博客园的平台上记录笔记 可以在以后复习时使用 后来我的同学开始推荐使用CSDN平台 于是我们两就转战CSDN啦 不知不觉 从3月份到现在也有
  • PyQt中的多线程QThread示例

    PyQt中的多线程 一 PyQt中的多线程 二 创建线程 2 1 设计ui界面 2 2 设计工作线程 2 3 主程序设计 三 运行结果示例 一 PyQt中的多线程 传统的图形用户界面应用程序都只有一个执行线程 并且一次只执行一个操作 如果用