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

news2025/1/12 12:03:44

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

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

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

🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,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时,定时器停止
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于LLM(Large Language Model,大语言模型)的智能问答系统

基于LLM(Large Language Model,大语言模型)的智能问答系统是一种利用先进的人工智能技术,尤其是自然语言处理(NLP)技术,来构建能够理解和回答用户问题的系统。这种系统通过训练大量文本数据&…

德国Testing Expo丨落幕不散场!知迪展台风采回顾

德国斯图加特国际展览中心,随着全球汽车产业的目光聚焦,Automotive Testing Expo Europe 2024圆满落幕。在这场汇聚了全球顶尖汽车测试技术的盛会中,知迪科技凭借卓越的技术实力和前瞻性的解决方案,成为了现场诸多专业观众的瞩目焦…

pydub、ffmpeg 音频文件声道选择转换、采样率更改

快速查看音频通道数和每个通道能力判断具体哪个通道说话;一般能量大的那个算是说话 import wave from pydub import AudioSegment import numpy as npdef read_wav_file(file_path):with wave.open(file_path, rb) as wav_file:params wav_file.getparams()num_cha…

红酒与舞蹈:舞动的味觉艺术

在艺术的海洋中,红酒与舞蹈总是能激起人们心中较温柔的涟漪。红酒以其深邃的色泽、馥郁的香气,诠释着味觉的艺术;而舞蹈,则以优雅的姿态、灵动的步伐,演绎着视觉的盛宴。当红酒遇上舞蹈,一场别开生面的艺术…

Ubuntu防火墙相关内容

Ubuntu防火墙相关的命令,主要用于日常使用过程中,忘记命令时查找方便,不用再去各种地方搜索了。以下命令均已root用户执行,如果是非root用户,需要添加sudo 查看防火墙的启用状态 ufw status 说明是启用状态。 启用防…

边缘和条件高斯相乘后的高斯分布形式【模式识别书】

边缘和条件高斯相乘后的高斯分布形式【模式识别书】 结论来自:《Pattern Recognition and Machine Learning》公式(2.115)

前端 原型 原型链的理解

概念 原型 对象中固有的 __proto__ 属性,该属性指向对象的 prototype 原型属性。 原型链 当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象 里找这个属性,这个原型对象又会有自己的原…

自然语言处理与Transformer模型:革新语言理解的新时代

引言 自然语言处理(NLP)是人工智能和计算机科学的一个重要分支,旨在使计算机能够理解、生成和处理人类语言。随着互联网和数字化信息的爆炸性增长,NLP在许多领域中的应用变得越来越重要,包括: 搜索引擎&am…

.NET 漏洞情报 | 某云平台存在SQL注入漏洞

01阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xf…

Django学习第二天

启动项目命令 python manage.py runserver 动态获取当前时间 javascript实现数据动态更新代码 <script>setInterval(function() {var currentTimeElement document.getElementById(current-time);var currentTime new Date();currentTimeElement.textContent Curren…

ESP32CAM物联网教学02

ESP32CAM物联网教学02 物联网门锁 小智来到姑姑家门口&#xff0c;按了门铃&#xff1b;还在公司上班的姑姑用电脑给小智开了门&#xff0c;让他先进屋休息。小智对物联网门锁产生了兴趣&#xff1a;什么是物联网&#xff1f;为什么这么厉害&#xff1f; 初识物联网 我们在百…

Mac/Linux安装JMeter压测工具

Mac安装JMeter压测工具 介绍 Apache JMeter™应用程序是开源软件&#xff0c;是一个100%纯的Java应用程序&#xff0c;旨在加载测试功能行为和衡量性能。它最初是为测试Web应用程序而设计的&#xff0c;但后来扩展到其他测试功能。 我能用它做什么&#xff1f; Apache JMet…

SwanLinkOS首批实现与HarmonyOS NEXT互联互通,软通动力子公司鸿湖万联助力鸿蒙生态统一互联

在刚刚落下帷幕的华为开发者大会2024上&#xff0c;伴随全场景智能操作系统HarmonyOS Next的盛大发布&#xff0c;作为基于OpenHarmony的同根同源系统生态&#xff0c;软通动力子公司鸿湖万联全域智能操作系统SwanLinkOS首批实现与HarmonyOS NEXT互联互通&#xff0c;率先攻克基…

二叉树的最近公共祖先-二叉树

236. 二叉树的最近公共祖先 - 力扣&#xff08;LeetCode&#xff09; ​ 递归 lson、rson左右子树&#xff1b; 深度优先遍历&#xff0c;遍历到p或者q就返回ture&#xff1b; class Solution { public:TreeNode* ans;bool dfs(TreeNode* root, TreeNode* p, TreeNode* q){i…

什么游戏加速器好用 网游加速器排行榜

玩游戏经常遇到卡顿和网络延迟等问题&#xff0c;尤其是外服游戏&#xff0c;这时候就需要一个安全稳定快速的加速器&#xff0c;我个人比较推荐“深度加速器。这款款加速器在稳定性和加速效果上都非常不错&#xff0c;而且用户口碑也很好。 在选择加速器时&#xff0c;确实有很…

DGMamba: Domain Generalization via Generalized State Space Model论文笔记

文章目录 DGMamba: Domain Generalization via Generalized State Space Model摘要动机DGMamba设计隐藏状态抑制(HSS)语义感知补丁细化(SPR)免先验扫描域上下文交换上下文patch识别 实验结果 DGMamba: Domain Generalization via Generalized State Space Model paper: https:/…

java到底是值传递还是引用传递

1、一定是值传递&#xff0c;给你的表象也有引用传递是因为对象传递的引用地址&#xff0c;我们在堆里更改了对象的属性值&#xff0c;但是地址没有变更&#xff0c;所以是值传递&#xff0c;可以参考方法的堆栈。 2、本质点看是否new一个新对象&#xff0c;如果new新对象&…

使用 llamaIndex 快速实现智能体

AI 智能体就是可以根据当前环境进行推理&#xff0c;并根据处理结果进行下一步的操作。简单来说 AI 智能体可以与外界环境进行交互&#xff0c;并根据结果执行更复杂的操作。本文将通过llamaIndex 实现一个简单的 Agent 实时获取数据&#xff0c;由于大模型是通过静态数据进行训…

Nginx 1.26.1最新版部署笔记

Nginx是一个高性能的 HTTP 和反向代理服务器&#xff0c;也是一个 IMAP/POP3/SMTP 代理服务器。 以下是 Nginx 的一些核心功能和特点&#xff1a; 高性能的 Web 服务器&#xff1a; Nginx 被设计为处理高并发连接&#xff0c;具有非常高的性能和稳定性。反向代理&#xff1a; …

买华为智驾,晚了肯定要后悔

文 | AUTO芯球 作者 | 雷慢 晚了就来不及了&#xff01; 你买华为系的车&#xff0c;薅羊毛真的要趁早。 华为ADS2.0高阶智驾正在慢慢恢复原价&#xff0c; 你看啊&#xff0c;就在昨天&#xff0c;华为宣布ADS智驾优惠后价格调到3万元&#xff0c; 只有6000元的优惠了。…