QT5之事件——包含提升控件

news/2024/9/25 15:22:16/

事件概述

 信号就是事件的一种,事件由用户触发;

鼠标点击窗口,也可以检测到事件;产生事件后,传给事件处理,判断事件类型,后执行事件相应函数;

类似单片机的中断(中断向量);

事件实验

工程准备

创建Qwidget基类工程且带UI

ui添加一个标签,这个标签拉得足够大,因为要显示

添加一个类文件Qwidget基类型的

更换为QLabel的基类

添加虚拟函数,属于保护类型;

输入void mousePressEvent(QMouseEvent *ev);如果参数不显示,删除括号且之后的删除;然后重新打括号

mylable.h

#ifndef MYLABLE_H
#define MYLABLE_H#include <QWidget>
#include<QLabel>
#include<QMouseEvent>
class MyLable : public QLabel
{Q_OBJECT
public:explicit MyLable(QWidget *parent = 0);
protected:void mousePressEvent(QMouseEvent *ev);void mouseReleaseEvent(QMouseEvent *ev);void mouseMoveEvent(QMouseEvent *ev);signals:public slots:
};#endif // MYLABLE_H

mylable.c

#include "mylable.h"
#include<QString>
#include<QDebug>
MyLable::MyLable(QWidget *parent) : QLabel(parent)
{this->setMouseTracking(true);//默认追踪鼠标,一开始不用点击窗口,就在追踪了
}void MyLable::mousePressEvent(QMouseEvent *ev)
{int i=ev->x();int j=ev->y();if(ev->button()==Qt::LeftButton)//左键{qDebug()<<"LeftButton";}else if(ev->button()==Qt::RightButton)//右键{qDebug()<<"RightButton";}else if(ev->button()==Qt::MidButton)//中间按键{qDebug()<<"MidButton";}//居中加粗指令QString str=QString("<center><h1>press mouse:(%1 ,%2)</h1></center>").arg(i).arg(j);this->setText(str);//设置标签内容为strqDebug()<<str;
}void MyLable::mouseReleaseEvent(QMouseEvent *ev)
{}void MyLable::mouseMoveEvent(QMouseEvent *ev)
{}

<center>     </center>    //居中指令  后面加的 /属于闭合标记,相当于括号的最后一半括号

<h1>     </h1>  //加粗指令      后面加的 /属于闭合标记,相当于括号的最后一半括号

 %1 %2 属于参数 1 和参数2; .arg(i) .arg(j) //添加对应变量

类提升

之前的标签基类,就变成了代码标签基类;

这个标签就成为了代码写的那个标标签;就可以显示文字了;

没有这个提升,就意味标签类不同,代码和UI的标签不是一个标签;

按键事件+定时器事件

开始一个定时器,分辨率为1ms 返回一个定时器ID

//停止定时器,只能使用kill

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include "mylable.h"
#include<QKeyEvent>//按键事件头
#include<QDebug>
#include<QTimerEvent>//定时器事件头
Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);ID1_time =this->startTimer(1000);//开始一个定时器,分辨率为1ms 返回一个定时器ID
}Widget::~Widget()
{delete ui;
}void Widget::keyPressEvent(QKeyEvent *e)//按键事件处理函数
{qDebug()<< (char)e->key();//打印按键if(e->key()==Qt::Key_A)//按键时这个就打印{qDebug()<< "Qt::Key_A";}}void Widget::timerEvent(QTimerEvent *t)//定时器事件处理函数
{if(t->timerId()==ID1_time)//判断当前的ID{static int time_counter;qDebug()<< time_counter++;if(time_counter==10){this->killTimer(ID1_time);//停止定时器,只能使用kill}}
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include<QTimerEvent>
namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();protected://虚拟函数,都使用保护void keyPressEvent(QKeyEvent *e);//虚拟函数,按键事件void timerEvent(QTimerEvent *t);//虚拟函数,定时器事件private:Ui::Widget *ui;int ID1_time;//定时器ID
};#endif // WIDGET_H

按钮事件的接收和忽略

事件相当于信号量;使用就没有了;

新建一个类MyButton属于Qwidget基类;

把新建的构造函数和基类改成继承于QPushButton;

ui放一个按钮提升类

设计一个按键和处理信号,和一个事件

实验结果:connet按键的信号相当于一个按下事件,但是被鼠标事件占用了,所以按键的信号等不到了;

所以按键connet的事件是等待不到的,事件被使用具有消耗性;

如下是按键的鼠标按下事件

如下是按键按下信号和槽

按钮按下相当于事件。但是鼠标按下事件已经接受;所以传递不了给下方这个了;

所以下方无法被打印

事件传递只能传递给父类组件(父类窗口)

使用e->accept();//接收事件,事件不会向下传递

 e->ignore();//忽略事件,事件会向下传递

代码设计为

按键的鼠标按下事件

void MyButton::mousePressEvent(QMouseEvent *e)
{if(e->button()== Qt::LeftButton){qDebug()<<"鼠标左按键被按下";e->ignore();//忽略事件,传递给父组件,也就是主窗口;//一般使用在关闭窗口,关闭窗口的时候,让事件传递;//没有ignore,也就是信号已经被这个处理,信号相当于信号量,使用就没有了}else//否则左键没被按下 ,不做处理{QPushButton::mousePressEvent(e);//没被按下,就传递给父组件}}

父类的鼠标按下


void Widget::mousePressEvent(QMouseEvent *e)
{qDebug()<<"+++++++++++++++++++";
}void Widget::closeEvent(QCloseEvent *e)
{int reg=QMessageBox::question(this,"question","是否需要关闭窗口");if(reg==QMessageBox::Yes){e->accept();//接收事件,事件不会向下传递}else{e->ignore();//忽略事件,事件会向下传递}}

event事件分发

事件分发分类分发给相应的事件处理函数;每个控件一个event。

在widget.h添加个

protected:

bool event(QEvent *e);//事件分发器 ,返回true就是说明事件已经被处理,停止向下传播

在widget.c分发器

bool Widget::event(QEvent *e)//
{//事件按照类型分发switch (e->type()) {case QEvent::Close:closeEvent(e);break;case QEvent::KeyPress:keyPressEvent(e);break;default:break;} ;if(e->type() == QEvent::Timer){QTimerEvent *env= static_cast<QTimerEvent * >(e);timerEvent(  env);//处理定时事件 屏蔽这个,永远不会分发return true;//返回true  表明事件被处理}else if(e->type() == QEvent::KeyPress)//事件是按键类型{QKeyEvent *env=static_cast<QKeyEvent*>(e) ; if(env->key()==Qt::Key_B) {qDebug()<<"bbbbbBBBB";}}else{return QWidget::event(e);//转发事件,继续下流事件}}

事件分发和过滤之间的关系:

过滤器

过滤器好处:不用单独给某个控件写事件分配EVENT;在过滤器里面可以,写一个EVENT程序,同时给多个器件使用;

成员的保护类添加如下

 bool eventFilter(QObject *obj, QEvent *e);//过滤器   过滤的obj控件  e过滤的事件

返回ture 就是停止过滤,过滤完成 ,flase  未过滤完成;

过滤器代码

bool Widget::eventFilter(QObject *obj, QEvent *e)
{if(obj== ui->pushButton)//这里可以并多个器件,相对写单个EVENT{if(e->type() == QEvent::MouseButtonPress){qDebug()<<"  鼠标被按下  ";//处理return true;//已经处理,不会继续传播}else{return QWidget::eventFilter(obj,e);//继续传播}}else{return QWidget::eventFilter(obj,e);//则继续传递下去}}

补充知识点:

类型转换:

 QTimerEvent *env= static_cast<QTimerEvent* >(e);

static_castt< >转换指令  ,符号里面是需要转换成的目标类型,(e)中的e是当前被转化数据;


http://www.ppmy.cn/news/1453956.html

相关文章

CMakeLists.txt语法规则:提供信息的变量说明一

一. 简介 前面几篇文章学习了 CMakeLists.txt语法中 部分常用命令。 接下来学习CMakeLists.txt语法中部分常用变量&#xff0c;变量也是 cmake 中的一个重头戏&#xff0c;cmake 提供了很多内置变量。每一个变量都有它自己的含义&#xff0c;可以通过如下链接地址查询到所有…

自注意力架构大成者_Transformer(Pytorch 17)

1 模型简介 在上节比较了 卷积神经网络&#xff08;CNN&#xff09;、循环神经网络&#xff08;RNN&#xff09;和 自注意力&#xff08;self‐attention&#xff09;。值得注意的是&#xff0c; 自注意力同时具有并行计算和最短的最大路径长度这两个优势。因此&#xff0c;使…

C语言中的goto语句

goto label; C 语言中的 goto 语句允许把控制无条件转移到同一函数内的被标记的语句。 #include <stdio.h> int main(){goto first;printf("我是你好\n");first:printf("nihao\n");second:printf("This is 2\n");return 0; } 使用goto会…

玩comfyui踩过的坑之使用ComfyUI_Custom_NODES_ALEKPET翻译组件问题

环境&#xff1a; 秋叶安装包&#xff0c;安装ComfyUI_Custom_NODES_ALEKPET组件或者直接下载网盘中的包&#xff0c;直接解压包到comfyui根目录/custom_nodes/&#xff0c;重启后&#xff0c;按指导文件操作。 注意&#xff1a;网盘指导包中有配置好的流程json文件&#xff0…

1-36 双列集合

一 Map集合 1.存储特点(重点记忆:) 以键值对(KEY-VALUE)形式存储 2.特点: ①将键值对看做对象进行存储 ②KEY 不能重复,VALUE可以重复 ③每一对K-V都是意义对应的映射关系 3.拓展:Map集合是双列集合,由两个单列集合组成的 分析KEY和VALUE所在的是什么种类集合 ①KEY不…

【Linux】对信号产生的内核级理解

一、键盘产生信号 键盘产生信号这里就要涉及一个重要的概念了&#xff0c;叫硬件中断。我这里会粗粒度地说一下键盘产生信号&#xff0c;以及信号被上层软件读到的过程&#xff0c;只是说一下我自己的理解。 1.1、硬件中断 硬件中断是计算机中的一种机制&#xff0c;它允许硬件…

谈谈Tcpserver开启多线程并发处理遇到的问题!

最近在学习最基础的socket网络编程&#xff0c;在Tcpserver开启多线程并发处理时遇到了一些问题&#xff01; 说明 在linux以及Windows的共享文件夹进行编写的&#xff0c;所以代码中有的部分使用 #ifdef WIN64 ... #else ... #endif 进入正题&#xff01;&#xff01;&…

问题 A: 实验11_4_初识链表

题目描述 已知一个正整数序列&#xff0c;个数未知&#xff0c;但至少有一个元素&#xff0c;你的任务是建立一个单链表&#xff0c;并使用该链表存储这个正整数序列&#xff0c;然后统计这个序列中元素的最大值与最小值&#xff0c;计算序列全部元素之和。正整数的输入用-1作…