当前位置: 首页 > article >正文

Qt事件处理(处理鼠标事件、键盘事件、定时器事件、窗口移动和大小变化事件)

事件处理

事件是应用程序内部或者外部产生的事情或者动作的统称。 在 Qt 中,事件是用一个对象来管理一个事件的。所有的事件对象都继承自抽象类 QEvent 。事件包括鼠标事件、键盘事件等,发出自 Qt 或操作系统本身。

QEvent1

处理事件一般通过重写相关的 Event 函数来实现,Qt 中所有的 Event 函数都是虚函数,都可以进行重写。这通常需要自定义一些控件类来继承 Qt 的控件类(如创建 Label 类继承 QLabel 类),但 ui 界面拖拽出来的控件类型都是 Qt 的内置控件类型(如 QLabel 类),重写不能影响到 ui 的控件。

但 Qt 也提供了解决方法,在 ui 界面对控件右键,选择 提升为… 可以将控件的类型改变成自定义类型(前提是必须继承了相关基类):

QEvent2

1. 处理鼠标事件

注意在重写事件时,包含对应的头文件,事件的函数不包含头文件并不会找不到相关的函数,但其 event 参数一定会找不到它的任何方法。

1.1 enterEvent和leaveEvent

enterEvent 和 leaveEvent 分别表示鼠标进入控件和离开控件的事件。

1.2 mousePressEvent和mouseReleaseEvent

鼠标点击左键、右键、滚轮、侧键等都会触发 mousePressEvent 和 mouseReleaseEvent 。如果想要确定究竟是哪些鼠标按键在触发 mousePressEvent 或 mouseReleaseEvent ,Qt有 Qt::LeftButton 用来表示左键、Qt::RightButton 用来表示右键等,使用代码用来判断什么按键在触发 mousePressEvent:

if(event->button() == Qt::LeftButton)
{
	qDebug()<<"按下左键";
}
else if(event->button() == Qt::RightButton)
{
	QDebug()<<"按下右键";
}

1.3 mouseDoubleClickEvent

当鼠标短时间两次点击时,就会触发 mouseDoubleClicked(鼠标双击事件)。但当鼠标双击时,也是会触发两次 mousePressEvent 事件的,所以代码中一定要做好单击和双击的区别判断,否则容易出现单双击同时触发的 Bug。

注意 mouseDoubleClickEvent 和 mouseDoubleClickedEvent 事件都是存在的,不要把这两个搞混了。


#include "label.h"
#include <QMouseEvent>


Label::Label(QWidget* parent):QLabel(parent)
{

}

void Label::mousePressEvent(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()<<"双击鼠标右键";
    }
}

1.4 mouseMoveEvent

mouseMoveEvent(鼠标追踪事件),由于鼠标只是小幅度移动就会产生大量的 mouseMoveEvent 事件,对程序运行的流畅度有很大影响,Qt 的 widget 默认关闭了鼠标追踪,所以即使重写了 mouseMoveEvent 也不会有效果。要想让鼠标追踪生效,需要使用 this->setMouseTracking(true) ,将鼠标追踪开启。

1.5 wheelEvent

wheelEvent(滚动事件),鼠标每次进行滚轮操作时都会触发这个事件,event 中有一个 delta() 会返回鼠标每次滚轮移动的值,向上为整数,向下为负数。

注意 wheelEvent 的头文件是 #include <QWheelEvent> ,且 event 的类型为 QWheelEvent*

#include "label.h"


Label::Label(QWidget* parent):QLabel(parent)
{

}

void Label::wheelEvent(QWheelEvent *event)
{
    qDebug()<<event->delta();
}


QEvent3

2. 键盘事件

2.1 keyPressEvent

keyPressEvent(键盘按键事件),当键盘上的按键被按下时就会触发该事件,QShorcut 就是基于该事件来设置快捷键的,实际我们也可以通过改写该事件的虚函数来实现快捷键的效果:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

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

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

void MainWindow::keyPressEvent(QKeyEvent* event)
{
    if(event->key()==Qt::Key_A && event->modifiers()==Qt::ControlModifier)
    {
        qDebug()<<"按下ctrl+A";
    }
}

注意普通按键是 event->key() ,Ctrl 是 event->modifiers()

3. 定时器事件

3.1 QTimerEvent

QTimerEvent(定时器事件)是与定时器有关的事件, QTimer 类就是通过 QTimerEvent 实现的。每一个定时器都有一个定时器的 ID 标识符,在程序中,可以通过不同的 ID 管理不同的定时器,使用多定时器实现程序的多样化。

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTimerEvent>

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

    timerID=this->startTimer(1000);//成员变量

}

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

void MainWindow::timerEvent(QTimerEvent* event)
{
    if(event->timerId()!=timerID)
    {
        return;
    }
    int value=ui->lcdNumber->intValue();
    if(value<0)
    {
        this->killTimer(this->timerID);
        return;
    }
    value-=1;
    ui->lcdNumber->display(value);
}

4. 窗口移动和大小变化事件

4.1 moveEvent

moveEvent(窗口移动事件),当窗口移动时就会触发该事件,可以通过该事件实时获取窗口此时的位置。

4.2 resizeEvent

resizeEvent(窗口大小变化事件),当窗口大小发生变化时就会触发该事件,可以通过该事件动态调整控件大小。


http://www.kler.cn/a/611531.html

相关文章:

  • Postman下载安装(Windows 11 专业版)
  • 【递归与动态规划(DP) C/C++】(1)递归 与 动态规划(DP)
  • 数据结构5(初):续写排序
  • 手搓全自动文章多平台发布系统:2、重要模块的设计
  • 国产化适配 - YashanDB、达梦数据库与MySQL 的兼容性及技术选型对比分析
  • R语言交互项-formula
  • 【C++】STL库_list 的模拟实现
  • 大数据学习栈记——HBase操作(shell java)
  • Couchbase存储引擎Magma和Couchstore
  • Stable Diffusion绘画插件(ControlNet )
  • Eclipse Debug 调试
  • 汇编(六)——汇编语言程序格式及MASM
  • OpenGL绘制文本
  • Vue的实例
  • Three.js 快速入门教程【十八】射线拾取模型——鼠标点击屏幕选中模型或物体
  • 【AI大模型】搭建本地大模型GPT-J:详细步骤及常见问题
  • 计算机视觉中的椭圆带权平均算法全解析
  • 【NLP 44、实践 ⑪ 用Bert模型结构实现自回归语言模型的训练】
  • Docker技术系列文章,第七篇——Docker 在 CI/CD 中的应用
  • 全息教学系统的软件开发,沉浸式数字沙盘展示系统如何改变历史教学