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

最近学习了很多关于python和pyqt5的只是,又由于工作需要,我自己写了一个程序,可以从电脑端向手push文件和安装apk。

接下来说说怎么实现的;跳转代码下载页

PyQt简介

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

以下简介一个基本的PyQt程序。
- 需要导入的类主要来自三个包
- from PyQt5.QtWidgets import 常用的控件
- PyQt5.QtCore 核心功能类,如QT,QThread,pyqtSignal
- PyQt5.QtGui UI类,如QFont
- 基础的程序结构:

import sys
from PyQt5.QtWidgets import QApplication, QWidget
class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.setupUI()

    def setupUI(self):
        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

如有错误,欢迎指正~

 


 

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值