Qt——事件简单介绍

目录

事件的概念

事件和处理函数的关联

鼠标移入和移出事件

题外话------自定义类如何使用QtDesigner

鼠标按下事件

鼠标释放事件

鼠标双击事件

鼠标移动事件

题外话------setMouseTracking(true)

鼠标滚动事件

键盘事件

定时器事件

窗口移动和大小改变事件


事件的概念

用户进行的各种操作,不仅会产生信号,也会产生事件。我们也可以给事件关联对应的处理函数,当事件触发时就执行到相应代码

实际上,事件本身是操作系统提供的机制Qt将操作系统的事件封装成Qt事件。尽管封装了,Qt事件使用起来还是比较复杂,所以Qt把Qt事件再封装成信号槽

不过Qt信号槽并没有提供所有用户动作对应的信号,因此我们有时还需要利用Qt事件机制来获取并处理用户动作**。**

所有的Qt事件都继承自QEvent:


事件和处理函数的关联

之前我们使用connect函数来把信号和信号槽关联起来。而在Qt事件机制中,我们需要做的是****重写Qt内置控件的事件处理函数,即创建继承自Qt内置控件类的新控件类并重写其事件处理函数,我们使用新的控件类自然就绑定了新的事件处理函数。

一句话,如果想对某控件的某些事件做出处理,就使用继承自该控件的子类控件并重写父类控件中对应事件的虚函数。


鼠标移入和移出事件

cpp 复制代码
#include "label.h"

label::label(QWidget * ptr):QLabel(ptr)
{
    this->setStyleSheet("border: 1px solid black; padding: 5px;");
}

void label::enterEvent(QEvent *event)
{
    qDebug()<<"鼠标进来了!";
}
void label::leaveEvent(QEvent *event)
{
    qDebug()<<"鼠标出去了!";
}

题外话------自定义类如何使用QtDesigner

我们现在的需求是,使用我们自己写的继承自Qt内置控件的控件,但是QtDesigner中的控件都是Qt内置的控件。

实际上我们可以先在QtDesigner拖入一个Qt内置控件,然后将其提升为我们写的子类控件,具体做法如下:

拖入一个内置QLabel控件,通过右侧对象树可知,当前使用的不是子类控件

右击选中的控件,点击提升为:

在上面两处填写你自己编写的控件类名称以及头文件名称并点击添加:

选中出现的行,然后点击提升,我们发现对象树上的类型已经改变了:


鼠标按下事件

cpp 复制代码
#include "label.h"

Label::Label(QWidget * ptr):QLabel(ptr)
{
    this->setStyleSheet("border: 1px solid black; padding: 5px;");
}

void Label::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        qDebug()<<"点击鼠标左键";
    }
    else if(event->button() == Qt::RightButton)
    {
         qDebug()<<"点击鼠标右键";
    }
    qDebug()<<"相对于lebel的坐标x:"<< event->x() <<"相对于lebel的坐标y"<<event->y();
    qDebug()<<"全局坐标x:"<< event->globalX() <<"全局坐标y"<<event->globalY();
}

鼠标释放事件

cpp 复制代码
#include "label.h"

Label::Label(QWidget * ptr):QLabel(ptr)
{
    this->setStyleSheet("border: 1px solid black; padding: 5px;");
}

void Label::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        qDebug()<<"点击鼠标左键";
    }
    else if(event->button() == Qt::RightButton)
    {
         qDebug()<<"点击鼠标右键";
    }
}

void Label::mouseReleaseEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        qDebug()<<"释放鼠标左键";
    }
    else if(event->button() == Qt::RightButton)
    {
         qDebug()<<"释放鼠标右键";
    }
}

鼠标双击事件

cpp 复制代码
#include "label.h"

Label::Label(QWidget * ptr):QLabel(ptr)
{
    this->setStyleSheet("border: 1px solid black; padding: 5px;");
}

void Label::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        qDebug()<<"点击鼠标左键";
    }
    else if(event->button() == Qt::RightButton)
    {
         qDebug()<<"点击鼠标右键";
    }
}

void Label::mouseReleaseEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        qDebug()<<"释放鼠标左键";
    }
    else if(event->button() == Qt::RightButton)
    {
         qDebug()<<"释放鼠标右键";
    }
}

void Label::mouseDoubleClickEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        qDebug()<<"双击鼠标左键";
    }
    else if(event->button() == Qt::RightButton)
    {
         qDebug()<<"双击鼠标右键";
    }
}

注意:双击事件触发之前,单击事件也是被触发的


鼠标移动事件

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    this->setMouseTracking(true);

}

void Widget::mouseMoveEvent(QMouseEvent *event)
{
    qDebug()<<"鼠标的x坐标是:"<<event->x()<<"鼠标的y坐标是:"<<event->y();
}

Widget::~Widget()
{
    delete ui;
}

题外话------setMouseTracking(true)

对于鼠标移动用来说,只要我们轻轻一划,就会产生很多移动事件,这会可能会导致客户端变得卡顿。

因此,控件默认是不追踪鼠标的移动的,在这种情况下,我们只有按住鼠标左键或者右键然后移动鼠标才会触发移动事件。

**想要达到鼠标只要移动就触发事件的效果就得告诉Qt你想追踪鼠标移动:**setMouseTracking(true)


鼠标滚动事件

cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //this->setMouseTracking(true);

}

void Widget::wheelEvent(QWheelEvent *event)
{
    //显示出鼠标滚动的距离
    qDebug()<<event->delta();
}

键盘事件

cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

}
void Widget::keyPressEvent(QKeyEvent *event)
{
    //如果用户按下了普通按键按键,会被存放到这儿
    int commonkey = event->key();
    //如果用户按下了ctrl,alt等特按键,会被存放到这儿
    int specialkey = event->modifiers();
    

    //Qt用数字表示按键类型,但提供给我们一些类型使用,我们使用这些类型区分出用户按下的是什么键
    
    //可以使用specialkey和commonkey判断用户是否按下了组合键(如果两个都不为0就是组合键),按下了什么组合键
    if(specialkey == Qt::ControlModifier && commonkey == Qt::Key_A)
    {
        qDebug()<<"用户按下了ctrl+A";
    }
    else if(specialkey == 0 && commonkey == Qt::Key_A)
    {
        qDebug()<<"用户按下了A";
    }
    else if(specialkey == 0 && commonkey == Qt::Key_B)
    {
        qDebug()<<"用户按下了B";
    }
}

定时器事件

cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //开启控件的定时器事件并设置间隔时间,返回定时器ID
    timer_id = this->startTimer(1000);
}

//定时器时间处理函数
void Widget::timerEvent(QTimerEvent *event)
{
    //一个控件可能有多个定时器,它们都会触发这个处理函数,所以我们用ID来区分它们
    int id = event->timerId();
    if(id!=timer_id)
    {
        return;
    }

    //如果倒计时小于等于0,就停止定时器
    int value = ui->lcdNumber->intValue();
    if(value<=0)
    {
        this->killTimer(id);
        return;
    }
    //否则就让倒计时-1
    else
    {
        ui->lcdNumber->display(value-1);
    }
}

窗口移动和大小改变事件

cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
}

void Widget::moveEvent(QMoveEvent *event)
{
    qDebug()<<event->pos();
}

void Widget::resizeEvent(QResizeEvent *event)
{
    qDebug()<<event->size();
}
相关推荐
子兮曰1 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰1 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
小羊没烦恼!1 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
前端小万1 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝1 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋1 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
伞伞悦读1 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
卡布鲁1 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
C语言小火车1 天前
C/C++ 为什么需要编译器?
开发语言·c++
霍霍的袁1 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio