PyQt5 多线程和异步刷新UI

这篇具有很好参考价值的文章主要介绍了PyQt5 多线程和异步刷新UI。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、基础程序

以下简介一个基本的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_())

二、Thread

方式一

//直接传入函数,启动线程,可以传入参数
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()

方式二

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进行更新。
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

五、moveToThread异步刷新UI

# -*- coding: utf-8 -*-

from PyQt5 import QtWidgets, QtCore
from PyQt5.QtCore import pyqtSignal, QObject, QThread
from QtUi import Ui_MainWindow
import sys
import time


class Work(QObject):
    count = int(0)
    count_signal = pyqtSignal(int)

    def __init__(self):
        super(Work, self).__init__()
        self.run = True

    def work(self):
        self.run = True
        while self.run:
            print(str(self.count))
            self.count += 1
            self.count_signal.emit(self.count)
            time.sleep(1)

    def work_stop(self):
        self.run = False


class MyWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MyWindow, self).__init__()
        self.setupUi(self)
        self.pushButton_Start.clicked.connect(self.workStart)
        self.pushButton_Stop.clicked.connect(self.workStop)

        self.thread = QThread()
        self.worker = Work()
        self.worker.count_signal.connect(self.flush)

        self.worker.moveToThread(self.thread)
        self.thread.started.connect(self.worker.work)
        self.thread.finished.connect(self.finished)

    def flush(self, count):
        self.label.setText(str(count))

    def workStart(self):
        print('button start.')
        self.pushButton_Start.setEnabled(False)
        self.thread.start()

    def workStop(self):
        print('button stop.')
        self.worker.work_stop()
        self.thread.quit()

    def finished(self):
        print('finish.')
        self.pushButton_Start.setEnabled(True)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    myshow = MyWindow()
    myshow.show()
    sys.exit(app.exec_())

QtUi.py文章来源地址https://www.toymoban.com/news/detail-666672.html

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'QtUi.ui'
#
# Created by: PyQt5 UI code generator 5.11.3
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(515, 208)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton_Start = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_Start.setGeometry(QtCore.QRect(280, 150, 92, 28))
        self.pushButton_Start.setObjectName("pushButton_Start")
        self.pushButton_Stop = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_Stop.setGeometry(QtCore.QRect(390, 150, 92, 28))
        self.pushButton_Stop.setObjectName("pushButton_Stop")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(60, 50, 381, 41))
        font = QtGui.QFont()
        font.setFamily("Adobe Arabic")
        font.setPointSize(28)
        self.label.setFont(font)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton_Start.setText(_translate("MainWindow", "开始"))
        self.pushButton_Stop.setText(_translate("MainWindow", "停止"))
        self.label.setText(_translate("MainWindow", "0"))

到了这里,关于PyQt5 多线程和异步刷新UI的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • pyqt5超详细多进程界面设计及打包流程(UI框架建构、多线程打包、.ui.qrc文件的转.py)

    项目的目标是制作一个目标检测的UI界面,实现各类目标的实时检测。在制作的过程中真的遇到了数不清的坑,坑死人了。我自己梳理一下方便下次做项目还掉坑里,顺便给大伙避避坑,当然每个人遇到的情况不同,如果我遇到的问题恰好帮助你解决问题了那就太好啦。 在终

    2024年02月04日
    浏览(40)
  • PyQt5多线程的执行和停止

    参考资料:哔哩哔哩 pyqt5 thread多线程示例 以下代码来自该视频,我自己手动实现了一下,当作一个模板来学习,欢迎大家一起学习。 运行示例 三个进程同时执行,并且可以单独控制暂停和继续执行。 以下给出运行代码: 完整程序参考:PyQt5 多线程执行和停止示例

    2024年02月16日
    浏览(36)
  • pyqt5 如何终止正在执行的线程?

    在 PyQt5 中终止正在执行的线程,可以通过一些协调的方法来实现。一般情况下,直接强行终止线程是不安全的,可能会导致资源泄漏或者程序异常。相反,我们可以使用一种协作的方式,通知线程在合适的时候自行退出。 以下是一种常见的方法,使用标志位来通知线程停止

    2024年02月14日
    浏览(38)
  • 【PyQT5教程】-02-UI组件

    QtWidgets 模块提供了多种按钮类,让你可以轻松地创建各种类型的按钮 QPushButton 是PyQt5中最常见的按钮类型之一,用于触发动作或执行操作。通过信号与槽机制,你可以将按钮的点击事件与特定的函数或操作关联起来。 QRadioButton 用于在一组选项中进行单选,用户只能选择其中

    2024年02月09日
    浏览(52)
  • PyQt5学习笔记--多线程处理、数据交互

    目录 1--引入多线程的原因 2--PyQt多线程的基本知识 3--多线程登录程序的实例 4--参考 ① 如果Qt只采用单线程任务的方式,当遇到数据处理慢的情形时,会出现GUI卡死的情况。 ② 使用下述例子展示单线程任务的缺陷: ③ 代码: ④ 结果展示: 当点击第一个button时,GUI会出现卡

    2023年04月16日
    浏览(49)
  • pyqt5中.ui转为.py

    在PyQt中,可以使用Qt Designer创建GUI的图形界面,设计完成后可以将其保存为.ui文件。但是,这种文件不能直接用于Python代码编程,必须将其转换为Python脚本,才能在Python程序中使用该界面。 将.ui文件转换为.py文件可以让您的程序更加灵活和方便,因为.py文件中包含了用于构建

    2024年02月04日
    浏览(38)
  • Pyqt5继承被覆盖的Ui界面类

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一、现象描述? 二、使用步骤 1.生成界面类Py文件,获取到生成的Ui界面类 2.新建一个py文件,继承Ui界面类 总结 提示:这里可以添加本文要记录的大概内容: PyQt使用designer每次设计Ui或者

    2024年02月03日
    浏览(44)
  • Python - PyQT5开发UI界面 - 环境搭建

    没有做过UI界面的都会把UI的制作想象的很神秘,我在刚开始的时候也是感觉异常神秘、很复杂、并且无从下手,不过在真正的做出来一个界面后,发现也并没有想象中的那么难,而且做出来可视化的东西所带来的成就感是超越代码本身的;不过整个过程也并不顺利,网上都是

    2023年04月23日
    浏览(47)
  • PYQT5 ui转py后的调用

    将程序按文件夹分好类,检查时更加清晰如先建立resource文件夹,内部含images(存放图片)、UI(存放UI文件),resource文件夹与main等设计界面程序并列,ui转成py时放在resource文件夹下边。  login_pane.py(将转换好的login.py引用,在此处对界面进行设计) 将做好的界面类引到主界面

    2024年02月06日
    浏览(73)
  • PyQt5 UI Designer使用pyqtgraph绘制波形

    包含了两个QWidget控件也可以是QGraphicsView控件类型。 两个控件分别提升为pyqtgraph.GraphicsLayoutWidget类型和pyqtgraph.PlotWidget GraphicsLayoutWidget类型通过addPlot方法添加波形数据,每个波形都占有独立的区域。 plt1 = self.graphicsLayout.addPlot(y=np.random.normal(size=1000), title=“温度”) plt2 = self.

    2024年02月06日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包