Qt事件处理机制

事件的概念

  • 在Qt中,以事件驱动UI工具集,包括信号和槽都依赖于Qt的事件处理机制。
  • 通常事件是由窗口系统或Qt自身产生的,用以响应所发生的各类事情。如:用户按下并释放键盘或鼠标、窗口缩放后重绘、定时器到时等。
  • 如下图:事件比信号更原始。一个下压式按钮首先感受到鼠标事件,在进行必要的处理以产生按钮下沉后弹起的视觉效果之后,才会发射clicked()信号。
    在这里插入图片描述

如何处理事件

  • 在Qt中,事件被封装为对象,所有的事件对象类型都继承自抽象类QEvent
  • 事件发生时,首先被调用的是QObject类中的虚函数event(),其参数(QEvent)标识了具体的事件类型
  • 在Qt桌面应用(Qt Widgets Application)开发中,QWidget类覆盖了其基类中的event()虚函数,根据具体事件调用具体事件处理函数:
    • void QWidget::mousePressEvent(QMouseEvent* e); // 鼠标按下事件
    • void QWidget::mouseReleaseEvent(QMouseEvent* e); // 鼠标抬起事件
    • void QWidget::mouseMoveEvent(QMouseEvent* e); // 鼠标移动事件
    • void QWidget::paintEvent(QPaintEvent* e); // 绘图事件

绘图事件

  • 通过绘图事件,可实现自定义的图像绘制。下列情况之一发生时,将触发窗口的绘制事件,即QWidget类的paintEvent()虚函数会被调用:
    • 窗口被创建后第一次显示出来
    • 窗口由隐藏状态转变为可见状态
    • 窗口由最小化状态转变为正常或最大化状态
    • 窗口因尺寸大小的变化需要呈现更多的内容
    • QWidget类的update()/repaint()成员函数被调用
  • 若希望在自己的窗口中显示某个图像,在QWidget的窗口子类中可重写绘图事件函数paintEvent,在其中可用QPainter(Qt二维图形引擎)实现指定的图像绘制、渲染等操作。
void XXX::paintEvent(QPaintEvent* e)
{// 创建画家对象QPainter painter(this)// 获取绘图所在矩形区域QRect rect = ui->frame->frameRect()// 坐标系平移,让rect和painter使用相同的坐标系rect.translate(ui->frame->pos());// 构建要绘制的图形对象QImage image(":/images/" + QString::number(m_index) + ".jpg");// 使用painter将image图片画到rectpainter.drawImage(rect, image);
}

定时器事件

实现机制

  • 定时器事件,由QObject提供
  • 定时器信号,由QTimer提供
通过定时器事件实现定时器
  • int QObject::startTimer(int interval); 启动定时器,以后每隔interval毫秒触发一次定时器事件,返回定时器ID。
  • void QObject::timerEvent(QTimerEvent* e); 虚函数,定时器事件处理函数
  • void QObject::killTimer(int id); 关闭参数id所标识的定时器

定时器摇奖部分代码

//初始化部分操作
void XXX::init(void)
{m_index = 0;isStarted = false;// 设置随机种子qsrand(QTime::currentTime().msec());// 加载“./photos”中所有图片到图片容器loadImages("./photos");
}// 开始按钮对应槽函数
void XXX::on_pushButton_clicked()
{if(isStarted == false){isStarted = true;	// 摇奖开始m_timer = startTimer(50);ui->pushButton->setText("停止");}else{isStarted = false;	// 摇奖结束killTimer(m_timer);ui->pushButton->setText("开始");}
}// 加载图片到容器功能
void XXX::loadImages(const QString& path)
{QDir dir(path);// 遍历当前目录所有图片QStringList listFiles = dir.entryList(QDir::Files);for(int i = 0; i < listFiles.size(); i++){QImage image(path + "/" + listFiles.at(i));m_vecImages << image;}// 递归遍历子目录中的图片QStringList listDirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);for(int i = 0; i < listDirs.size(); i++){loadImages(path + "/" + listDirs.at(i));}	
}// 定时器事件处理函数
void XXX::timerEvent(QTimerEvent*  e)
{m_index = qrand() % m_vecImages.size();update();	//将触发绘图事件处理函数
}// 绘图事件处理函数
void XXX::paintEvent(QPaintEvent* e)
{QPainter painter(this);QRect rect = ui->frame->frameRect();rect.translate(ui->frame->pos());painter.drawImage(rect, m_vecImages[m_index]);
}
通过QTimer实现定时器

QTimer m_timer

  • void start(int msec); 开启定时器
  • void stop(); 停止定时器
    每当定时器到时后会发射信号:timeout
    connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeout()));

鼠标和键盘事件

鼠标事件

QWidget类定义了以下虚函数提供对鼠标事件的处理

  • virtual void mousePressEvent(QMouseEvent* e); //鼠标按下
  • virtual void mouseReleaseEvent(QMouseEvent* e); //鼠标抬起
  • virtual void mouseMoveEvent(QMouseEvent* e); //鼠标移动
  • virtual void mouseDoubleClickEvent(QMouseEvent* e); //鼠标双击
// 鼠标左键拖动QLabel//鼠标按下
void XXX::mousePressEvent(QMouseEvent* e)
{// 是否鼠标左键if(e->button() == Qt::LeftButton){// 获取label所在矩形区域QRect rect = ui->m_label->frameRect();// 坐标平移:让rect和鼠标使用相同的坐标系rect.translate(ui->m_label->pos());// 判断当前鼠标点击位置是否在QLabel的矩形区域中if(rect.contains(e->pos())){m_drag = true;		// 可拖拽m_pos = ui->m_label->pos() - e->pos();		// 鼠标相对QLabel的位置}}
}
// 鼠标抬起
void XXX::mouseReleaseEvent(QMouseEvent* e)
{if(e->button() == Qt::LeftButton){m_drag = false;}
}
// 鼠标移动
void XXX::mouseMoveEvent(QMouseEvent* e)
{if(m_drag){// 计算QLabel要移动的新位置QPoint newPos = e->pos() + m_pos;QSize s1 = size();		// 获取父窗口的大小QSize s2 = ui->m_label->size();		//获取QLabel的大小 // 设置QLabel移动的范围限制// x: 0 ~ s1.width() - s2.width()if(newPos.x() < 0){newPos.setX(0);}else if(newPos.x() > s1.width() - s2.width()){newPos.setX(s1.width() - s2.width());}// y: 0 ~ s1.height() - s2.height()if(newPos.y() < 0){newPos.setY(0);}else if(newPos.y() > s1.height() - s2.height()){newPos.setY(s1.height() - s2.height());}// 移动QLabel到新位置ui->m_label->move(newPos);}	
}

键盘事件

QWidget类定义了以下虚函数提供对键盘事件的处理

  • virtual void keyPressEvent(QKeyEvent* e); // 按键按下
  • virtual void keyReleaseEvent(QKeyEvent* e); // 按键抬起
// 键盘方向键控制QLabel移动
void XXX::keyPressEvent(QKeyEvent* e)
{//QLabel所在位置的x坐标int x = ui->m_label->pos().x();//QLabel所在位置的y坐标int y = ui->m_label->pos().y();// 向上移动(每次移动10像素)if(e->key() == Qt::Key_Up){ui->m_label->move(x, y - 10);}else if(e->key() == Qt::Key_Down){ui->m_label->move(x, y + 10);} else if(e->key() == Qt::Key_Left){ui->m_label->move(x - 10, y);}else if(e->key() == Qt::Key_Right){ui->m_label->move(x + 10, y);}
}

参考:达内教育QT图形框架

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

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

相关文章

【慧游鲁博】【11】小程序端·游览画卷修改·支持图片url格式·结合图床上传和加载·数据对接

文章目录 需求修改细节前端主要修改点说明&#xff1a;前端传递格式 后端ArtifactItem 类&#xff1a;ScrollServiceImpl 类&#xff1a;修改 InfoPanel 结构重构 ScrollHorizontalRollComposer修改后的 ScrollHorizontalRollComposer移除冗余代码修改总结 数据流图片格式兼容性…

攻克SQL审核“最后堡垒”!PawSQL首发T-SQL存储过程深度优化引擎

为什么存储过程审核那么难&#xff1f; 存储过程将数据操作逻辑固化在数据库层&#xff0c;一次编译、多次执行&#xff0c;既能大幅提升性能&#xff0c;也能通过权限隔离增强安全。然而&#xff0c;正因其逻辑复杂、分支众多&#xff0c;存储过程内部的 SQL 审核与优化常常成…

计算机网络零基础完全指南

目录 🌐 什么是计算机网络 生活中的类比 计算机网络的本质 网络的发展历程 🏠 网络IP详解(重点) 1. IP地址是什么? 生活例子:IP地址就像门牌号 IP地址的格式 IP地址的二进制表示 2. IP地址的分类详解 A类地址(大型网络) B类地址(中型网络) C类地址(小…

DL___线性神经网络

1&#xff09;回归&#xff08;regression&#xff09;是能为一个或多个自变量与因变量之间关系建模的一类方法。 在自然科学和社会科学领域&#xff0c;回归经常用来表示输入和输出之间的关系。 2&#xff09;一般回归是和预测有关&#xff0c;比如预测价格(房屋&#xff0c;…

WSL2安装与使用(USB、GPU、虚拟机、图形界面)

文章目录 前言WSL2安装&#xff08;手动安装&#xff09;WSL2基础使用VS Code与WSL2配合使用连接USB设备WSL2中使用GPU&#xff08;RTX5060Ti 16G&#xff09;与虚拟机兼容使用&#xff08;Virtual Box&#xff09;图形与桌面环境WSL消失&#xff08;灾难性故障&#xff09;问题…

uni-app项目实战笔记16--实现头部导航栏效果

先来看效果&#xff1a; 要求&#xff1a;顶部导航栏要始终固定在上方&#xff0c;不随页面上下拖动而消失。 代码实现&#xff1a; 1.定义一个自定义导航栏组件&#xff1a;custom-nav-bar.vue&#xff0c;并写入如下代码&#xff1a; <template><view class"…

web3.js 核心包及子模块

. 核心包 (web3) 功能:提供基础连接、工具函数和核心功能。 包含子模块: web3.eth - 以太坊区块链交互 web3.utils - 辅助工具函数 web3.shh - Whisper 协议(已废弃) web3.bzz - Swarm 去中心化存储(已废弃) web3.net - 网络相关功能 web3.contract - 智能合约交互 web3.…

训练检测之前的视频抽帧

接下来安装pytorch Previous PyTorch Versions 视频抽帧 import cv2def extract_frames(video_path, output_folder, frame_rate1):"""从视频中抽取帧。:param video_path: 视频文件的路径:param output_folder: 存储帧的文件夹路径:param frame_rate: 抽取的…

智能家居HA篇 二、配置Home Assistant并实现外部访问

智能家居HA篇 一、Win10 VM虚拟机安装 Home Assistant 手把手教学 二、通过Cpolar配置Home Assistant并实现外部访问 文章目录 智能家居HA篇前言一、内网穿透工具&#xff08;cpolar&#xff09;二、映射HA端口1.访问cpolar仪表2.创建账号并登录3.创建隧道 三、HA设置及公网访…

day09——Java基础项目(ATM系统)

文章目录 Java项目实战&#xff1a;手把手开发ATM银行系统&#xff08;附完整源码&#xff09;一、系统架构设计1. 三层架构模型2. 核心数据结构 二、核心功能实现1. 开户功能&#xff08;含唯一卡号生成&#xff09;2. 登录安全验证3. 存取款业务4. 安全转账实现 三、账户安全…

计算机网络:(五)信道复用技术,数字传输系统,宽带接入技术

计算机网络&#xff1a;&#xff08;五&#xff09;信道复用技术&#xff0c;数字传输系统&#xff0c;宽带接入技术 前言一、信道复用技术1. 为什么需要复用技术&#xff1f;2. 频分复用&#xff08;FDM&#xff09;3. 时分复用&#xff08;TDM&#xff09;4. 统计时分复用&am…

【期末总结】计算机网络

【期末总结】计算机网络 参考链接&#xff1a;计算机网络知识点全面总结&#xff08;有这一篇就够了&#xff01;&#xff01;&#xff01;&#xff09;-CSDN博客 一.概述 1.1 计算机网络的分类 按照网络的作用范围&#xff1a;广域网&#xff08;WAN&#xff09;、城域网&a…

React学习001-创建 React 应用

React学习001-创建 React 应用 1、安装node.js2、安装构建工具2.1 核心特性2.2 性能对比​​2.3 适用场景​​ 3、创建应用4、项目启动参考文章 1、安装node.js 这里建议安装nvm多版本管理node.js&#xff0c;想用哪个版本&#xff0c;一条命令即可~ 多版本管理node.js 2、安…

(cvpr2025) Adaptive Rectangular Convolution for Remote Sensing Pansharpening

论文&#xff1a;(cvpr2025) Adaptive Rectangular Convolution for Remote Sensing Pansharpening 代码&#xff1a;https://github.com/WangXueyang-uestc/ARConv.git 这个论文研究的是全色与多光谱图像的融合。作者认为现有的基于CNN的方法中&#xff0c;传统的卷积存在两个…

【图像处理入门】7. 特征描述子:从LBP到HOG的特征提取之道

摘要 特征描述子是图像处理中提取图像本质信息的关键工具。本文将深入讲解局部二值模式(LBP)与方向梯度直方图(HOG)两种经典特征描述子的原理、实现方法及应用场景。结合OpenCV代码示例,展示如何利用LBP提取纹理特征、使用HOG进行目标检测,帮助读者掌握从图像中提取有效…

AI 应用开发的‘核心枢纽’:Dify、Coze、n8n、FastGPT、MaxKB、RAGFlow 等六大平台全面对决

在人工智能与自动化流程日益普及的当下&#xff0c;各类平台如雨后春笋般涌现&#xff0c;成为构建智能应用与自动化工作流的 “核心枢纽”。其中&#xff0c;Dify、Coze、n8n、FastGPT、MaxKB、RAGFlow 备受瞩目&#xff0c;它们各自具备独特的功能与优势&#xff0c;适用于不…

RV1126+OPENCV对视频流单独进行视频膨胀/腐蚀操作

一.RV1126OPENCV对视频流进行视频膨胀操作的大体流程图 思路&#xff1a;初始化VI与VENC模块&#xff0c;之后开启两个线程&#xff0c;一个线程从VI模块获取视频流数据&#xff0c;用Opencv的Mat将其转成Mat矩阵之后进行用dilate膨胀&#xff0c;将膨胀之后的视频数据用send函…

Cordova + Vue 移动端视频播放组件(支持 HLS + 原生播放器兜底)

在混合 App 中&#xff0c;移动端使用 标签播放视频经常踩坑&#xff0c;尤其是格式兼容、跨域限制、WebView 差异等问题。 本文介绍一个通用的 Cordova 视频播放组件&#xff1a;优先 HTML5 播放&#xff0c;播放失败自动提示用户使用系统播放器&#xff0c;并支持原生插件兜底…

【Linux】掌握vim编译器使用——详细教程

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、Vim的三种核心模式解析 二、高效编辑核心命令大全 1. 光标快速导航 2. 文本编辑四连击 3. 高效搜索替换 三、Vim神技&#xff1a;批量注释与多文件编辑 1. 批量…