【python】PyQt5事件机制、定时器原理分析和实战演练

在这里插入图片描述
在这里插入图片描述

✨✨ 欢迎大家来到景天科技苑✨✨

🎈🎈 养成好习惯,先赞后看哦~🎈🎈

🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。
🏆《博客》:Python全栈,前后端开发,小程序开发,云原生K8S,人工智能,js逆向,App逆向,网络系统安全,数据分析,PyQt5,tkinter,Django,fastapi,flask等框架,linux,shell脚本等实操经验,网站搭建,数据库等分享。

所属的专栏:PyQt5桌面应用开发,零基础到进阶应用实战
景天的主页:景天科技苑

文章目录

  • PyQt5事件机制
    • PyQt5事件处理的API
    • PyQt5事件机制演练
  • PyQt5定时器
    • 定时器的操作方法有两种
      • (1)利用每个对象包含的timerEvent函数
      • (2)利用定时器模块QTimer

PyQt5事件机制

PyQt为事件处理提供了两种机制:高级的信号与槽机制,以及低级的事件处理机制。信号与槽可以说是对事件处理机制的高级封装。事件机制更偏向于底层。

常见事件类型:
键盘事件:按键按下和松开。
鼠标事件:鼠标指针移动,鼠标按下和松开。
拖放事件:用鼠标进行拖放。
滚轮事件:鼠标滚轮滚动。
绘屏事件:重绘屏幕的某些部分。
定时事件:定时器到时。
焦点事件:键盘焦点移动。
进入/离开事件:鼠标指针移入Widget内,或者移出。
移动事件:Widget的位置改变。
大小改变事件:Widget的大小改变。
显示/隐藏事件:Widget显示和隐藏。
窗口事件:窗口是否为当前窗口。
PyQt提供了如下5种事件处理和过滤方法(有弱到强):

重新实现事件函数,比如mousePressEvent(),keyPressEvent()等等。
重新实现QObject.event()。
安装时间过滤器。
在QApplication中安装事件过滤器。
重新实现QAppliction的notifiy()方法。

在这里插入图片描述

在这里插入图片描述

PyQt5事件处理的API

在这里插入图片描述

PyQt5事件机制演练

import sys
from PyQt5.Qt import *

#通过继承,重新notify方法
#事件会分发给对象里面的notify方法
class App(QApplication):
    #notify第一个参数是控件类型(事件接收者),第二个是事件类型
    def notify(self, recevier, evt):
        #notify会监控所有的事件,对事件进行分发。为了打印鼠标点击按钮产生的事件,我们进行了过滤
        #过滤事件接收者是按钮,事件类型是鼠标按钮按下
        #evt属于QEvent类型。QEvent类型里面有个type方法,用来判断事件类型
        if recevier.inherits("QPushButton") and evt.type() == QEvent.MouseButtonPress:
            print(recevier, evt)

        #优先调用子类notify方法,由于我们没有写具体功能,什么也做不了,会报错,为了防止程序报错,需要将父类的notify方法返回
        #这行代码就是负责分发的
        return super().notify(recevier, evt)

#写个子类,过滤event事件类型
class Btn(QPushButton):
    #事件会分发给按钮对象的event方法,event里面包含很多事件
    def event(self, evt):
        if evt.type() == QEvent.MouseButtonPress:
            print(evt)
        #根据事件类型再次进行分发,根据不同事件调用不同事件函数
        return super().event(evt)

    #重写鼠标被按下事件函数
    def mousePressEvent(self, *args, **kwargs):
        print("鼠标被按下了......")
        #返回父类鼠标事件函数,进而发射信号给槽,调用槽函数
        #如果不返回,则不会发射信号给槽
        return super().mousePressEvent(*args, **kwargs)



app = App(sys.argv)

window = QWidget()
#设置主题
window.setWindowTitle("事件机制")
btn = Btn(window)
btn.setText("按钮")
btn.move(100, 100)

def cao():
    print("按钮被点击了")

#按键按下
btn.pressed.connect(cao)

window.show()

sys.exit(app.exec_())

运行

在这里插入图片描述

点击按钮
可见事件被触发
在这里插入图片描述

在这里插入图片描述

PyQt5定时器

在基于PyQt5的应用程序开发过程中经常会遇到一些需要循环执行的任务,即定时多长时间任务循环一次。
常用于数据库定时更新、界面刷新、内存清理、脚本任务运行、进度条等需要定时更新的程序段,小到某一参数的定时更新,大到整个线程任务的更新、程序段的循环定时执行。

本文将详细介绍如何在PyQt5中使用定时器,包括定时器的基本原理、创建和使用定时器的方法以及一些实际应用案例。

定时器的操作方法有两种

  • 方法一:利用每个对象包含的timerEvent函数

  • 方法二:利用定时器模块 需要 from PyQt5.QtCore import QTimer

(1)利用每个对象包含的timerEvent函数

API介绍已经案例演示
在这里插入图片描述

# 0. 导入需要的包和模块
from PyQt5.Qt import *
import sys

#自定义一个类继承QObejct
# class MyObject(QObject):
#     def timerEvent(self, evt): #重写对象的定时器函数
#         print(evt, "1")

#自定义个类继承QLabel,可以重写父类方法,尤其是timerEvent对象的定时器函数
class MyLabel(QLabel):
    #增加参数接收*args, **kwargs
    def __init__(self, *args, **kwargs):
        # 当我们继承某个类时,需要调用父类构造方法
        #加载父类初始化方法
        super().__init__(*args, **kwargs)
        self.setText("10")
        self.move(235, 235)
        self.setStyleSheet("font-size: 28px;")

    #设置标签上展示的初始数字
    def setSec(self, sec):
        self.setText(str(sec))

    def startMyTimer(self, ms):
        #可以创建多个,每个startTimer返回的id不同
        #每个一定的时间,就会自动执行对象中的timerEvent函数
        #参数1 间隔时间,单位毫秒
        self.timer_id = self.startTimer(ms,timerType=Qt.PreciseTimer) #启动对象定时器函数

    def timerEvent(self, *args, **kwargs):
        print("倒计时进行中")
        # 1. 获取当前的标签的内容
        current_sec = int(self.text())
        current_sec -= 1
        #将内容以字符串形式展示,整形数据没法直接放进来
        self.setText(str(current_sec))

        #当前数字减为0时,停止定时器
        if current_sec == 0:
            print("倒计时停止")
            # 释放对象的定时器函数
            self.killTimer(self.timer_id)


class MyWidget(QWidget):
    def startMyTimer(self, ms):
        #可以创建多个,每个startTimer返回的id不同
        #每个一定的时间,就会自动执行对象中的timerEvent函数
        #参数1 间隔时间,单位毫秒
        self.widget_id = self.startTimer(ms,timerType=Qt.PreciseTimer) #启动对象定时器函数

    def timerEvent(self, *args, **kwargs):
        #获取当前窗口的高和宽
        current_w = self.width()
        current_h = self.height()
        #定时器每执行一次,窗口长和高都加10
        self.resize(current_w + 10, current_h + 10)
        print("当前窗口高度", current_h)

        #设置当前窗口高度达到550时,停止定时器
        if current_h == 550:
            print("widget停止")
            # 释放对象的定时器函数
            self.killTimer(self.widget_id)



if __name__ == '__main__':

    # 1. 创建一个应用程序对象
    app = QApplication(sys.argv)

    # 2. 控件的操作
    # 2.1 创建控件
    window = MyWidget()
    # 2.2 设置控件
    window.setWindowTitle("QObject定时器的使用")
    window.resize(500, 500)
    window.startMyTimer(1000)


    #创建第二个控件
    label = MyLabel(window)
    label.setSec(10)
    label.startMyTimer(500)


    # 2.3 展示控件
    window.show()
    # 3. 应用程序的执行, 进入到消息循环
    sys.exit(app.exec_())

运行
在这里插入图片描述

当到达临界值,定时器停止
在这里插入图片描述

(2)利用定时器模块QTimer

需要导包 from PyQt5.QtCore import QTimer
QTimer 的事件可以通过 QTimer.timeout.connect() 信号槽绑定到对应的处理函数上。
例如,在下面的示例中,定义了一个 onTimer() 函数,每当定时器时间到达时,就会执行这个函数。

要启动 QTimer 定时器,需要调用 QTimer.setInterval() 方法,并传入时间间隔,单位为毫秒(ms)。
例如,传入 1000 表示每隔 1000 毫秒(即 1 秒)会触发一次 operate()。需要注意的是,定时器不仅仅是触发一次,而是持续按照设定的时间间隔触发,直到调用 QTimer.stop() 方法停止。

import sys

from PyQt5.Qt import *


class win(QWidget): #创建一个类,为了集成控件
    # 增加参数接收*args, **kwargs
    def __init__(self, *args, **kwargs):
        # 当我们继承某个类时,需要调用父类构造方法
        super().__init__(*args, **kwargs)
        self.setWindowTitle('定时器的使用')
        self.resize(300,300)
        self.num=0
        self.setup_ui()


    def setup_ui(self):

        #添加个标签,初始化标签
        self.lable = QLabel(self)
        self.lable.move(120,120)
        self.lable.setStyleSheet("font-size: 28px;")

        self.timer = QTimer(self)  # 初始化一个定时器
        # 设置计时间隔;单位毫秒
        self.timer.setInterval(1000)
        self.timer.timeout.connect(self.operate)  # 每次计时到时间时发出信号
        #启动定时器,也可以在这里设置时间间隔,例如:self.timer.start(1000) 表示每秒执行一次
        self.timer.start()


    #定时器要执行的动作
    def operate(self):
        self.num=self.num+1
        print(self.num)
        #动态设置标签显示数字
        self.lable.setText(str(self.num))

        #设置定时器停止阈值
        if self.num == 5:
            print("计时停止")
            self.timer.stop()





if __name__=='__main__':
    app=QApplication(sys.argv)  #创建应用
    window=win()
    window.show()
    sys.exit(app.exec_())

运行
在这里插入图片描述

当num数值增加到5时,定时器停止
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/767934.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

哨兵1SAR空间数据包协议数据单元文档(五)

《哨兵1SAR空间数据包协议数据单元》文档对数据包的结构进行了详细描述,并提供了用户数据的格式和解码算法。 原文链接: 哨兵1SAR空间数据包协议数据单元文档英文版 同系列中的其他文章篇链接: 哨兵1SAR空间数据包协议数据单元文档(一) 哨兵1…

亚太万人eVTOL展!2024深圳eVTOL将于9月登陆鹏城

2024年以来,北京、上海等十多个省市,先后发布了鼓励低空经济发展的行动方案,其中,eVTOL(电动垂直起降航空器)成为低空经济最火热的细分赛道。2023年,中国eVTOL产业规模达9.8亿元,同比…

【C++】相机标定源码笔记- RGB 相机与 ToF 深度传感器校准类

类的设计目标是为了实现 RGB 相机与 ToF 深度传感器之间的高精度校准,从而使两种类型的数据能够在同一个坐标框架内被整合使用。这在很多场景下都是非常有用的,比如在3D重建、增强现实、机器人导航等应用中,能够提供更丰富的场景信息。 -----…

64位Office API声明语句第120讲

跟我学VBA,我这里专注VBA, 授人以渔。我98年开始,从源码接触VBA已经20余年了,随着年龄的增长,越来越觉得有必要把这项技能传递给需要这项技术的职场人员。希望职场和数据打交道的朋友,都来学习VBA,利用VBA,起码可以提高…

工厂模式之简单工厂模式

文章目录 工厂模式工厂模式分为工厂模式的角色简单工厂模式案例代码定义一个父类,三个子类定义简单工厂客户端使用输出结果 工厂模式 工厂模式属于创造型的模式,用于创建对象。 工厂模式分为 简单工厂模式:定义一个简单工厂类,根…

Vue3的模板语法插值表达式用法

在template中输入“5 3” &#xff0c;是没有运算能力的&#xff0c;只会把字符直接显示出来&#xff0c;代码如下&#xff1a; <template><view>这是demo</view><view>5 3</view><navigator open-type"navigateBack"><vi…

永劫无间国服延迟高、报错、卡顿的处理措施一览

永劫无间国服延迟高、报错、卡顿怎么办&#xff1f;快速解决办法分享 第一个办法&#xff1a;改善延迟 如果是一直遇到永劫无间国服延迟高、报错、卡顿的问题&#xff0c;重启游戏也不管用的话&#xff0c;那应该就是网络问题&#xff0c;玩家可以启动雷神&#xff0c;让其快速…

服了!DELETE 同一行记录也会造成死锁!!

1 问题背景 “哥们&#xff0c;又双叒叕写了个死锁&#xff0c;秀啊&#xff01;&#x1f60f;” 就算是经常写死锁的同学看到估计都会有点懵&#xff0c;两条一模一样的 DELETE 语句怎么会产生死锁呢&#xff1f; 2 MySQL 锁回顾 看到这里的靓仔肯定对 MySQL 的锁非常了解&…

红酒与建筑:品味历史与艺术的交汇

在时间的长河中&#xff0c;红酒与建筑都是人类智慧的结晶&#xff0c;它们各自承载着历史的厚重与艺术的韵味。当这两者交汇时&#xff0c;仿佛是一场穿越时空的对话&#xff0c;将我们带入一个既古老又现代、既深沉又温柔的世界。今天&#xff0c;就让我们一起走进这个奇妙的…

企业消费采购成本和员工体验如何实现“鱼和熊掌“的兼得?

有企业说企业消费采购成本和员工体验的关系好比是“鱼和熊掌”&#xff0c;无法兼得&#xff1f; 要想控制好成本就一定要加强管控&#xff0c;但是加强管控以后&#xff0c;就会很难让员工获得满意的体验度。如果不加以管控&#xff0c;员工自由度增加了&#xff0c;往往就很难…

为什么要在成像应用中使用图像采集卡?

达到最大产量是工业和工厂自动化的关键标准之一。提高传感器分辨率和帧速率有助于实现这一目标&#xff0c;但也使带宽达到极限&#xff0c;并提出了新的传输问题。当前高带宽接口(如10GigE、相机直接与PC连接和嵌入式系统)的实现促使成像应用的许多用户询问如何以最佳配置最优…

Day63 代码随想录打卡|回溯算法篇---电话号码的字母组合

题目&#xff08;leecode T17&#xff09;&#xff1a; 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 方法&#xff1a;…

CCS方形低角度光源实现更均匀的照射

机器视觉系统中&#xff0c;光源设计作为图像成像效果的关键&#xff0c;今天的光源系列分享——FPQ3系列。 特点&#xff1a; ・从4个方向以低角度照射均匀扩射光的方型低角度光源。 ・实现比上一代产品2倍的高输出。白色和蓝色的亮度提高至2倍&#xff0c;红色的亮度提高至…

app单页下载页源码带管理后台

新版带后台管理APP应用下载页,自动识别安卓苹果下载页&#xff0c;带管理后台&#xff0c;内置带3套App下载模板带中文模板/英文模板随时切换。 app单页下载页源码带管理后台

保存到redis中的token乱码了

示图&#xff1a; 原因是缓存保存到redis需要序列化操作&#xff0c;没有序列化会出现这样的问题 序列化redis第一步&#xff1a; package com.abliner.test.configure.redis;import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annota…

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【17】认证服务01

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【17】认证服务01 环境搭建验证码倒计时短信服务邮件服务验证码短信形式&#xff1a;邮件形式&#xff1a; 异常机制MD5参考 环境搭建 C:\Windows\System32\drivers\etc\hosts 192.168.…

西南交通大学【算法分析与设计实验3】

实验3.3 任务分配问题 实验目的 &#xff08;1&#xff09;理解穷举法典型算法的求解过程。 &#xff08;2&#xff09;学习穷举法的时间复杂度分析方法&#xff0c;并通过实验验证算法的执行效率。 &#xff08;3&#xff09;学会如何利用穷举法求解具体问题&#xff0c;了…

51单片机嵌入式开发:STC89C52操作8八段式数码管原理

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 STC89C52操作8八段式数码管原理 1 8位数码管介绍1.1 8位数码管概述1.2 8位数码管原理1.3 应用场景 2 原理图图解2.1 74HC573原理2.2 74HC138原理2.3 数码管原理 3 数码管程序…

现代智能宠物喂食器方案定制

现代智能宠物喂食器不仅具备定时喂食功能&#xff0c;帮助宠物主人管理宠物的饮食时间和食量&#xff0c;还加入了录音功能和摄像头&#xff0c;使得宠物主人即使不在家也能与宠物保持互动&#xff0c;并实时监控宠物的状况。此外&#xff0c;一些产品还具备紧急预警功能&#…

Docker加速器配置指南:提升镜像下载速度的秘诀 加速安装Mysql Redis ES

在安装 Docker 镜像时&#xff0c;由于官方镜像下载速度较慢&#xff0c;我们可以使用阿里云的镜像加速器来提升下载速度。 使用阿里云镜像加速器 首先&#xff0c;找到并配置阿里云的镜像加速器。安装教程如下&#xff1a; 登录阿里云&#xff0c;进入容器镜像服务。直达链…