当前位置:首页 » 《资源分享》 » 正文

【QT】Qt事件

3 人参与  2024年11月07日 18:42  分类 : 《资源分享》  评论

点击全文阅读


在这里插入图片描述
个人主页~


Qt系统相关

一、Qt事件1、事件介绍2、事件的处理label.hlabel.cpp 3、QKeyEvent按键事件(1)按下单个按键(2)组合键 4、QMouseEvent鼠标事件(1)鼠标单击事件(2)鼠标移动事件(3)鼠标滚轮操作 5、QTimeEvent定时器事件(1)QTimerEvent(2)QTimer 6、事件分发器7、事件过滤器mylabel.hmylabel.cppwidget.hwidget.cpp

一、Qt事件

1、事件介绍

事件是应用程序内外部产生的事情以及动作的统称,常见的所有事件例如鼠标事件QMouseEvent,键盘事件QKeyEvent等等都是继承自QEvent

2、事件的处理

在Qt中几乎所有的Event函数都是虚函数,我们可以通过C++多态,重写Event函数

首先创建一个QWidget项目,在项目处右键AddNew一个C++类文件,勾选Include QWidget以及Add Q_OBJECT,在帮助文档中找到要重写事件的定义,此时需要我们选择主题,我们选择QWidget Class,然后将函数名以及参数复制到代码中,然后重写函数,在ui中拖一个label进去,将label提升为我们自己新建一个Label类,与刚才我们AddNew的C++类文件名相同,点击添加后点击提升,在Label.h中包含上QLabel头文件,修改构造函数让Label继承自QLabel,修改一下参数为QWidget* parent

label.h

#ifndef LABEL_H#define LABEL_H#include <QLabel>class Label : public QLabel{    Q_OBJECTpublic:    Label(QWidget* parent = nullptr);    void enterEvent(QEvent *event);};#endif // LABEL_H

label.cpp

#include "label.h"#include <QDebug>Label::Label(QWidget* parent) : QLabel(parent){}void Label::enterEvent(QEvent *event){    qDebug()<<"鼠标进入";}

在这里插入图片描述

QEvent

3、QKeyEvent按键事件

(1)按下单个按键

void Widget::keyPressEvent(QKeyEvent *event){    if(event->key() == Qt::Key_A)    {        qDebug() << event->key();    }}

在这里插入图片描述

(2)组合键

在帮助中搜索Qt::KeyboardModifier,其中定义了在处理键盘事件时对应的修改键
在这里插入图片描述
这其中的英文解释很简单就不翻译了,主要是第五条这里的Meta键,在Windows上指Windows键,在Mac上指Command键,第六条Numlock处于打开状态,第七条是输入法切换的

void Widget::keyPressEvent(QKeyEvent *event){    if(event->modifiers() == Qt::ControlModifier)    //检查是否按下了Ctrl键,event->modifiers返回当前按键事件的修饰键状态    {        if(event->key() == Qt::Key_A)        {            qDebug() << "按下Ctrl+A";        }    }}

在这里插入图片描述

4、QMouseEvent鼠标事件

通过帮助文档找到QMouseEvent类
在这里插入图片描述
这里有关于鼠标的三个事件:鼠标的点击、鼠标的移动、鼠标滚轮操作,鼠标的点击又分为单击、双击以及按下之后释放的过程,鼠标点击的这三个方法使用方法相同,我们以鼠标单击举例
在这里插入图片描述

(1)鼠标单击事件

void Widget::mousePressEvent(QMouseEvent *event){    if(event->button() == Qt::LeftButton)    {        qDebug() << "鼠标左键";    }    if(event->button() == Qt::RightButton)    {        qDebug() << "鼠标右键";    }    if(event->button() == Qt::MidButton)    {        qDebug() << "鼠标中键";    }}

在这里插入图片描述

(2)鼠标移动事件

因为鼠标是一个随时移动的量,如果一直盯着鼠标那会是一个很大的开销,所以我们在默认状态下是是不追踪鼠标的,当我们通过设置setMouseTracking函数为true来实时捕获鼠标信息

当我们快速移动鼠标时,我们可以看到控制台打印出数据的速度明显下降,会出现卡顿,所以我们一般不使用这个函数

(3)鼠标滚轮操作

void Widget::wheelEvent(QWheelEvent *event){    static int x = 0;    x += event->delta();    if(event->delta() > 0)    {        qDebug() << "滚轮前滑"<<x;    }    if(event->delta() < 0)    {        qDebug() << "滚轮后滑"<<x;    }}

其中event->delta()返回滚动的距离
在这里插入图片描述

5、QTimeEvent定时器事件

(1)QTimerEvent

QTimerEvent类用来描述一个定时器事件,通过startTimer()函数来开启定时器

Widget::Widget(QWidget *parent)    : QWidget(parent)    , ui(new Ui::Widget){    ui->setupUi(this);    timer_id1 = startTimer(1000);    timer_id2 = startTimer(2000);    //设置两个定时器,第一个每一秒发送一个信号,第二个每两秒发送与一个信号}void Widget::timerEvent(QTimerEvent *event){    if(event->timerId() == timer_id1)//检查收到的定时器事件ID是否与timer_id1相同    {        static int n1 = 1;        ui->label->setText(QString::number(n1++));    }    if(event->timerId() == timer_id2)    {        static int n2 = 1;        ui->label_2->setText(QString::number(n2++));    }}

timerevent

(2)QTimer

QTimer类来实现一个定时器

Widget::Widget(QWidget *parent)    : QWidget(parent)    , ui(new Ui::Widget){    ui->setupUi(this);//开启一个定时器,设置开始按钮的槽函数为每过1s触发一次信号    QTimer* timer = new QTimer(this);    connect(ui->pushButton,&QPushButton::clicked,[=]()    {       timer->start(1000);    });//设置每次信号触发将label数字加一    connect(timer,&QTimer::timeout,[=]()    {        static int n = 1;        ui->label->setText(QString::number(n++));    });//停止按钮暂停定时器    connect(ui->pushButton_2,&QPushButton::clicked,[=]()    {        timer->stop();    });//计时按钮打印当前的时间    connect(ui->pushButton_3,&QPushButton::clicked,[=]()    {        qDebug() << ui->label->text();    });}

timer

6、事件分发器

每个继承自QObject或者QObject类本身都可以在本类中重写bool event(QEvent* event)函数,来实现相关事件的捕获和拦截

在Qt中,我们发送的事件都是传给了QObject对象的event()函数,我们处理这个事件就是要重写这个event函数,它本身不会去处理事件,而是根据事件类型调用不同的事件处理函数

事件分发器就是用来分发事件,同时可以做拦截操作的,主要通过bool event(QEvent* event)函数实现,true为拦截

void Widget::mousePressEvent(QMouseEvent *event){    qDebug() <<"在mousePressEvent下点击鼠标";}bool Widget::event(QEvent *event){//如果事件类型是鼠标按下,打印信息并返回拦截    if(event->type() == QEvent::MouseButtonPress)    {        qDebug() << "在event下点击鼠标";        return true;    }//如果事件类型不是鼠标按钮按下,调用基类QWidget的event方法来处理其他类型的事件,并返回结果    return QWidget::event(event);}

event_bool

当然我们自己在实现的时候会发现点击过快会发生"在mousePressEvent下点击鼠标"也出现在打印信息中,这是因为点击过快被系统认为是双击,此时第二次点击不会被event拦截,就打印出"在mousePressEvent下点击鼠标"

7、事件过滤器

事件过滤器是应用程序分发到event事件分发器之前做的一次更高级的拦截
因为使用事件分发器重写event函数实现拦截会很麻烦,因为event函数是protected的,所以需要继承已有类,每有一个组件需要实现拦截就要重写一个event函数

mylabel.h

class MyLabel : public QLabel{    Q_OBJECTpublic:    explicit MyLabel(QWidget *parent = nullptr);//在自定义类中写一个事件分发器    void mousePressEvent(QMouseEvent *event);    bool event(QEvent *event);};

mylabel.cpp

//内容与上面事件分发器相同,就是在一个自定义类中实现的事件分发器void MyLabel::mousePressEvent(QMouseEvent *event){    qDebug() << "mousePressEvent";}bool MyLabel::event(QEvent *event){    if(event->type() == QEvent::MouseButtonPress)    {        qDebug() << "event";        return true;    }    return QWidget::event(event);}

widget.h

//声明事件bool eventFilter(QObject* obj,QEvent* event);

widget.cpp

Widget::Widget(QWidget *parent)    : QWidget(parent)    , ui(new Ui::Widget){    ui->setupUi(this);//给label安装事件过滤器,对象是当前窗口this    ui->label->installEventFilter(this);}//实现该事件类似于上面,也是对应的返回true,其他的交给父类处理bool Widget::eventFilter(QObject *obj, QEvent *event){    if(obj == ui->label)    {        if(event->type() == QEvent::MouseButtonPress)        {            qDebug() << "eventFilter";            return true;        }    }    return QWidget::eventFilter(obj,event);}

event_bool_super


今日分享就到这了~

在这里插入图片描述


点击全文阅读


本文链接:http://m.zhangshiyu.com/post/183837.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1