浅谈PyQt5中异步刷新UI和Python多线程总结
目前任务需要做一个界面程序,PyQt是非常方便的选择,QT丰富的控件以及python方便的编程。近期遇到界面中执行一些后台任务时界面卡死的情况,解决了在这里记录下。
PyQt
PyQt简介
PyQt是Qt的python接口,PyQt的文档较少,但接口和函数可以完全参照Qt,继承了Qt中大量的控件以及信号机制,十分方便。以下简介一个基本的PyQt程序。
-需要导入的类主要来自三个包
-fromPyQt5.QtWidgetsimport常用的控件
-PyQt5.QtCore核心功能类,如QT,QThread,pyqtSignal
-PyQt5.QtGuiUI类,如QFont
-基础的程序结构:
classExample(QWidget): def__init__(self): super()__init__() self.setupUI() defsetupUI(): 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,这样主线程会阻塞
实现方式一
直接传入函数,启动线程,可以传入参数
importtime,threading defthreadFunction(): whileTrue: 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方法
fromthreadingimportThread importtime classExample(Thread): def__init__(self): super().__init__() defrun(self): whileTrue: 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类变量,在实例连接信号就可以了
classExample(QWidget): signal=pyqtSignal()#括号里填写信号传递的参数 #发射信号 deffunc(self): self.signal.emit() #使用信号 a=Example() a.signal.connect(callback) #槽函数 defcallback(): pass
UI刷新
在界面中,通常用会有一些按钮,点击后触发事件,比如去下载一个文件或者做一些操作,这些操作会耗时,如果不能及时结束,主线程将会阻塞,这样界面就会出现未响应的状态,因此必须使用多线程来解决这个问题。
注意:
1.PyQt5不能在子线程中刷新线程,这样会造成界面卡死,因此不能使用常规的多线程刷新UI。
2.但是又必须要实现子线程和主线程之间的通信,否则无法得知任务是否完成。因此使用PyQt5中的QThread,这样既可以使用信号机制,又能够使用多线程。
3.当启动多线程后,注册信号,槽函数为主线程中的函数,当任务完成后,发射信号,在主线程中对UI进行更新。
注:由于需要注册信号,thread需要是继承自QThread的类
classExample(QThread): signal=pyqtSignal()#括号里填写信号传递的参数 def__init__(self): super().__init__() def__del__(self): self.wait() defrun(self): #进行任务操作 self.signal.emit()#发射信号 #UI类中 defbuttonClick(self) self.thread=Example() self.thread.signal.connect(self.callback) self.thread.start()#启动线程 defcallbakc(self): pass
如有错误,欢迎指正~
以上这篇浅谈PyQt5中异步刷新UI和Python多线程总结就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。