首页 > 其他分享 >【QT】Qt事件

【QT】Qt事件

时间:2024-11-04 09:19:59浏览次数:3  
标签:Widget 鼠标 label ui 事件 Qt event QT

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


Qt系统相关

一、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_OBJECT
public:
    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()<<"鼠标进入";
}

在这里插入图片描述

<iframe allowfullscreen="true" data-mediaembed="csdn" frameborder="0" id="enO63q85-1730299045063" src="https://live.csdn.net/v/embed/431710"></iframe>

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++));
    }
}

<iframe allowfullscreen="true" data-mediaembed="csdn" frameborder="0" id="r43fmuQd-1730385192803" src="https://live.csdn.net/v/embed/432058"></iframe>

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();
    });
}

<iframe allowfullscreen="true" data-mediaembed="csdn" frameborder="0" id="N9Hi59ow-1730388616362" src="https://live.csdn.net/v/embed/432061"></iframe>

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);
}

<iframe allowfullscreen="true" data-mediaembed="csdn" frameborder="0" id="2CPVZ81g-1730460135697" src="https://live.csdn.net/v/embed/432071"></iframe>

event_bool

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

7、事件过滤器

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

mylabel.h

class MyLabel : public QLabel
{
    Q_OBJECT
public:
    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);
}

<iframe allowfullscreen="true" data-mediaembed="csdn" frameborder="0" id="LrAB0so1-1730464365766" src="https://live.csdn.net/v/embed/432201"></iframe>

event_bool_super


今日分享就到这了~

在这里插入图片描述

标签:Widget,鼠标,label,ui,事件,Qt,event,QT
From: https://blog.csdn.net/s_little_monster/article/details/143246300

相关文章

  • activemq - mqttv3
    相比于mqtt-client,mqttv3使用的人相对多些,如果出现问题,好排查一些。activemq部署MQTT服务查看文件:conf\activemq.xml,如果包含下面内容,activemq本身已经包含MQTT服务,不需要任何其它配置。activemq不局限于下面这些,还可以继续扩展,比如:NIO、SSL。前往官网查看:https://a......
  • JavaScript(事件监听,点击事件,事件类型:鼠标事件mouseenter,mouseleave,焦点事件focus,blur,
    事件监听目标:能够给DOM元素添加事件监听什么是事件?事件是在编程时系统内发生的动作或者发生的事情比如用户在网页上单击一个按钮什么是事件监听?就是让程序检测是否有事件产生,一旦有事件触发,就立即调用一个函数做出响应,也称为绑定事件或者注册事件比如鼠标经过显示下拉菜......
  • JavaScript 事件监听
    一事件绑定点击查看代码1.通过HTML标签中的事件属性进行绑定<inputtype="button"onclick='on()’>functionon(){alert("我被点了");}2.通过DOM元素属性绑定<inputtype="button"id="btn">document.getElementById("btn").o......
  • Qt基础学习(三)------第一个程序
    前言    开始进入第一个程序,编写helloword来了解一下程序结构。软件    安装完成后,在开始界面会有一个如下图标的软件。,双击打开,进入到Qt软件界面。进projects,点击NEW新建项目新建窗口项目语言使用默认使用msvc2015的64版本,或者自己有的版本......
  • 解决QT5升级Creator 14.x后出现launch debugger红色报错问题-OK
       QT5升级QtCreator14.x后出现launchdebugger红色报错,QT5C++项目可以编译运行,但无法调试运行。经试验:选择DesktopQT5.15.2MinGW64-bit调试运行无法启动,红色报错。增加安装QT6.7.3后,选择DesktopQT6.7.3MinGW64-bit可以成功进行调试运行。   经过多次测试,发......
  • QT中TextEdit或者QLineEdit以十六进制显示数组数据
    QT中TextEdit以十六进制显示数组数据在Qt(一种跨平台的C++图形用户界面应用程序开发框架)中,如果你想在QTextEdit中以十六进制格式显示数组数据,你可以使用以下步骤:创建一个QTextEdit控件在你的Qt应用程序中创建一个QTextEdit控件,用于显示文本。QTextEdit*textEdit=......
  • Nuxt.js 应用中的 nitro:init 事件钩子详解
    title:Nuxt.js应用中的nitro:init事件钩子详解date:2024/11/3updated:2024/11/3author:cmdragonexcerpt:nitro:init是Nuxt3中的一个生命周期钩子,在Nitro初始化完成后被调用。这个钩子允许开发者注册Nitro钩子,并直接与Nitro进行交互。这种灵活性使得开发者......
  • Qt/C++地图动态绘制折线多边形矩形圆形标注点/可编辑拖动调整大小和位置
    一、前言说明无论哪一家的地图,都提供了调用函数绘制各种覆盖物,但是有时候的场景是希望进入添加覆盖物模式,然后每次在地图上按下都自动生成对应的覆盖物比如圆形,这样就不需要用户提前知道经纬度坐标等参数,而是让用户自己在地图上拾取即可,这样灵活性就极大的提高了。百度地图和腾讯......
  • 基于YOLO11/v10/v8/v5深度学习的危险驾驶行为检测识别系统设计与实现【python源码+Pyq
    《博主简介》小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~......
  • 在 .NET 中深入了解事件总线的使用与实现
    引言在现代软件架构中,尤其是微服务和事件驱动设计中,事件总线(EventBus)是实现组件间解耦和异步通信的重要工具。事件总线通过允许不同组件之间以松耦合的方式进行交互,从而提升了系统的灵活性和可维护性。本文将详细探讨在.NET中实现事件总线的方式,包括其工作原理、使用方法以及......