浅谈PyQt5中异步刷新UI和Python多线程总结


Posted in Python onDecember 13, 2019

目前任务需要做一个界面程序,PyQt是非常方便的选择,QT丰富的控件以及python方便的编程。近期遇到界面中执行一些后台任务时界面卡死的情况,解决了在这里记录下。

PyQt

PyQt简介

PyQt是Qt的python接口,PyQt的文档较少,但接口和函数可以完全参照Qt,继承了Qt中大量的控件以及信号机制,十分方便。以下简介一个基本的PyQt程序。

- 需要导入的类主要来自三个包

- from PyQt5.QtWidgets import 常用的控件

- PyQt5.QtCore 核心功能类,如QT,QThread,pyqtSignal

- PyQt5.QtGui UI类,如QFont

- 基础的程序结构:

class Example(QWidget):
 def __init__(self):
  super()__init__()
  self.setupUI()

 def setupUI():
  self.show()
  pass
  # 设置UI
if __name__ == '__main__':
 app = QApplication(sys.argv) # 启动app
 ex = Example() # 实例化一个自己派生的
 # 也可以实例化库中的控件
 # q = QPushButton()
 # q.show()
 sys.exit(app.exec_())

总体来说:

1. 首先实例化APP

2. 实例化预定义控件或者自己派生自库中的控件,记得调用show()函数

3. 执行并安全退出

Python中的多线程

python中的多线程使用较为方便,主要使用threading.Thread类:

1. 线程启动使用start()函数

2. 如果需要等待线程执行使用join,这样主线程会阻塞

实现方式一

直接传入函数,启动线程,可以传入参数

import time, threading
def threadFunction():
 while True:
  print(11111)
  time.sleep()
# 用于命名,可以通过threading.current_thread().name获得
t = threading.Thread(target=threadFunction, name='funciton')
# 如果线程有参数
t = threading.Thread(target=threadFunction, args=(), name='funciton')
t.start()

实现方式二

继承Thread,重写run方法

from threading import Thread
import time

class Example(Thread):
 def __init__(self):
  super().__init__()

 def run(self):
  while True:
   time.sleep(1)
   print(11111111)

if __name__ == '__main__':
 a = Example()
 a.start()
 a.join()
 print(222222222)

注意:

1. 使用join方法会让主线程阻塞在这里,等待子线程结束,在里面可以设置阻塞的时间

2. a.setDaemon(True)在start前设置,可以保证在主线程终止时,子线程也终止

信号机制

QT中的信号机制能够方便的编写回调。

1. 很多控件都有预定的信号如clicked,直接使用clicked.connect连接槽函数即可。

2. 继承自Qt的类,然后自定义一个signal类变量,在实例连接信号就可以了

class Example(QWidget):
 signal = pyqtSignal() # 括号里填写信号传递的参数
 # 发射信号
 def func(self):
  self.signal.emit()

# 使用信号
a = Example()
a.signal.connect(callback)

# 槽函数
def callback():
 pass

UI刷新

在界面中,通常用会有一些按钮,点击后触发事件,比如去下载一个文件或者做一些操作,这些操作会耗时,如果不能及时结束,主线程将会阻塞,这样界面就会出现未响应的状态,因此必须使用多线程来解决这个问题。

注意:

1. PyQt5不能在子线程中刷新线程,这样会造成界面卡死,因此不能使用常规的多线程刷新UI。

2. 但是又必须要实现子线程和主线程之间的通信,否则无法得知任务是否完成。因此使用PyQt5中的QThread,这样既可以使用信号机制,又能够使用多线程。

3. 当启动多线程后,注册信号,槽函数为主线程中的函数,当任务完成后,发射信号,在主线程中对UI进行更新。

注:由于需要注册信号,thread需要是继承自QThread的类

class Example(QThread):
 signal = pyqtSignal() # 括号里填写信号传递的参数
 def __init__(self):
  super().__init__()

 def __del__(self):
  self.wait()

 def run(self):
  # 进行任务操作
  self.signal.emit() # 发射信号

# UI类中
def buttonClick(self)
 self.thread = Example()
 self.thread.signal.connect(self.callback)
 self.thread.start() # 启动线程

def callbakc(self):
 pass

如有错误,欢迎指正~

以上这篇浅谈PyQt5中异步刷新UI和Python多线程总结就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python批量修改文件名的实现代码
Sep 01 Python
Python常用小技巧总结
Jun 01 Python
Python解析并读取PDF文件内容的方法
May 08 Python
11个Python3字典内置方法大全与示例汇总
May 13 Python
华为校园招聘上机笔试题 扑克牌大小(python)
Apr 22 Python
Python实现结构体代码实例
Feb 10 Python
基于python实现数组格式参数加密计算
Apr 21 Python
tensorflow实现将ckpt转pb文件的方法
Apr 22 Python
PySide2出现“ImportError: DLL load failed: 找不到指定的模块”的问题及解决方法
Jun 10 Python
详解python中的异常和文件读写
Jan 03 Python
python3.9.1环境安装的方法(图文)
Feb 02 Python
python中取整数的几种方法
Nov 07 Python
python编写微信公众号首图思路详解
Dec 13 #Python
selenium+python实现自动登陆QQ邮箱并发送邮件功能
Dec 13 #Python
python中设置超时跳过,超时退出的方式
Dec 13 #Python
python opencv实现gif图片分解的示例代码
Dec 13 #Python
python多进程并发demo实例解析
Dec 13 #Python
使用Matplotlib 绘制精美的数学图形例子
Dec 13 #Python
python plotly画柱状图代码实例
Dec 13 #Python
You might like
基于mysql的论坛(2)
2006/10/09 PHP
IStream与TStream之间的相互转换
2008/08/01 PHP
PHP 引用文件技巧
2010/03/02 PHP
phpize的深入理解
2013/06/03 PHP
php函数实现判断是否移动端访问
2015/03/03 PHP
php从完整文件路径中分离文件目录和文件名的方法
2015/03/13 PHP
JS模拟多线程
2007/02/07 Javascript
Web跨浏览器进程通信(Web跨域)
2013/04/17 Javascript
Jquery显示和隐藏元素或设为只读(含Ligerui的控件禁用,实例说明介绍)
2013/07/09 Javascript
Javascript中this的用法详解
2014/09/22 Javascript
js实现使用鼠标拖拽切换图片的方法
2015/05/04 Javascript
js倒计时简单实现方法
2015/12/17 Javascript
浅谈JavaScript的闭包函数
2016/12/08 Javascript
JS实现弹出下载对话框及常见文件类型的下载
2017/07/13 Javascript
Angular 作用域scope的具体使用
2017/12/11 Javascript
利用Javascript开发一个二维周视图日历
2017/12/14 Javascript
浅谈vue引入css,less遇到的坑和解决方法
2018/01/20 Javascript
javascript与PHP动态往类中添加方法对比
2018/03/21 Javascript
webstorm和.vue中es6语法报错的解决方法
2018/05/08 Javascript
vux uploader 图片上传组件的安装使用方法
2018/05/15 Javascript
对angularJs中$sce服务安全显示html文本的实例
2018/09/30 Javascript
vue表单验证你真的会了吗?vue表单验证(form)validate
2019/04/07 Javascript
10个最受欢迎的 JavaScript框架(推荐)
2019/04/24 Javascript
JavaScript静态作用域和动态作用域实例详解
2019/06/17 Javascript
微信小程序多列表渲染数据开关互不影响的实现
2020/06/05 Javascript
python输出当前目录下index.html文件路径的方法
2015/04/28 Python
Python实现查找系统盘中需要找的字符
2015/07/14 Python
Django 中使用流响应处理视频的方法
2018/07/20 Python
利用pandas读取中文数据集的方法
2018/07/25 Python
Python如何实现远程方法调用
2020/08/07 Python
师范生自我鉴定范文
2013/10/05 职场文书
交通事故协议书范文
2014/04/16 职场文书
2014高考励志标语
2014/06/05 职场文书
2014幼儿园教师师德师风演讲稿
2014/09/10 职场文书
2015年小学体育工作总结
2015/05/22 职场文书
Python开发之QT解决无边框界面拖动卡屏问题(附带源码)
2021/05/27 Python