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

目前任务需要做一个界面程序,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多线程总结就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。

以上是 浅谈PyQt5中异步刷新UI和Python多线程总结 的全部内容, 来源链接: utcz.com/z/356993.html

回到顶部