问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Qt事件处理完全指南:从概念到实战

创作时间:
作者:
@小白创作中心

Qt事件处理完全指南:从概念到实战

引用
CSDN
1.
https://m.blog.csdn.net/YoungMLet/article/details/140236827

在Qt开发中,事件处理是实现用户交互的核心机制。本文将详细介绍Qt中的事件概念、处理方法,以及鼠标和键盘事件的具体实现,通过多个代码示例帮助读者快速掌握Qt事件处理的基本技巧。

Qt事件概述

事件是应用程序内部或外部产生的动作的统称。在Qt中,所有事件都继承自抽象类QEvent。事件可以由用户操作(如鼠标点击、键盘输入)触发,也可以由系统自动发出(如定时器事件)。常见的Qt事件类型如下:

事件处理方法

在Qt中,事件处理通常通过重写相关的事件函数来实现。这些函数都是虚函数,可以被子类重新实现。例如,要处理鼠标进入和离开事件,可以直接重写enterEvent()leaveEvent()函数。

示例1:处理鼠标进入事件

  1. 新建Qt项目,基类选择QWidget,同时勾选UI界面文件。
  2. 在UI文件中添加一个Label,并为其添加边界框。
  3. 新建一个名为MyLabel的类,继承自QWidget。
  4. mylabel.h中声明enterEvent()函数:
#ifndef MYLABEL_H
#define MYLABEL_H

#include <QWidget>

class MyLabel : public QWidget
{
    Q_OBJECT
public:
    explicit MyLabel(QWidget *parent = nullptr);
    
    // 鼠标进入事件
    void enterEvent(QEvent* event);

signals:

};

#endif // MYLABEL_H
  1. mylabel.cpp中实现enterEvent()函数:
#include "mylabel.h"
#include <QDebug>

MyLabel::MyLabel(QWidget *parent) : QWidget(parent)
{}

void MyLabel::enterEvent(QEvent *event)
{
    qDebug() << "鼠标进入事件";
}
  1. 将Label提升为MyLabel类。
  2. 修改基类为QLabel,并在mylabel.cppmylabel.h中进行相应修改:
#ifndef MYLABEL_H
#define MYLABEL_H

#include <QLabel>

class MyLabel : public QLabel
{
    Q_OBJECT
public:
    explicit MyLabel(QWidget *parent = nullptr);

    // 鼠标进入事件
    void enterEvent(QEvent* event);

signals:

};

#endif // MYLABEL_H
#include "mylabel.h"
#include <QDebug>

MyLabel::MyLabel(QWidget *parent) : QLabel(parent)
{}

void MyLabel::enterEvent(QEvent *event)
{
    qDebug() << "鼠标进入事件";
}
  1. 运行程序,当鼠标进入Label时,控制台将输出"鼠标进入事件"。

示例2:获取鼠标点击坐标

mylabel.h中声明mousePressEvent()函数:

class MyLabel : public QLabel
{
    Q_OBJECT
public:
    explicit MyLabel(QWidget *parent = nullptr);

    // 鼠标进入事件
    void enterEvent(QEvent* event);
    
    // 鼠标移动事件
    void mousePressEvent(QMouseEvent* ev);

signals:

};

mylabel.cpp中实现mousePressEvent()函数:

#include "mylabel.h"
#include <QDebug>
#include <QMouseEvent>

MyLabel::MyLabel(QWidget *parent) : QLabel(parent)
{}

void MyLabel::enterEvent(QEvent *event)
{
    qDebug() << "鼠标进入事件";
}

void MyLabel::mousePressEvent(QMouseEvent *ev)
{
    // qt中的格式化字符串
    QString str1 = QString("鼠标按下了 x = %1, y = %2").arg(ev->x()).arg(ev->y());
    qDebug() << str1;
}

示例3:区分鼠标左右键

void MyLabel::mousePressEvent(QMouseEvent *ev)
{
    // 鼠标左键
    if(ev->button() == Qt::LeftButton) {
        // x, y 为基于窗口的坐标
        QString str = QString("鼠标左键: x = %1, y = %2").arg(ev->x()).arg(ev->y());
        qDebug() << str.toUtf8().data();
    }

    // 鼠标右键
    if(ev->button() == Qt::RightButton) {
        // globalX, globalY 为基于屏幕的坐标
        QString str = QString("鼠标右键: x = %1, y = %2").arg(ev->globalX()).arg(ev->globalY());
        qDebug() << str.toUtf8().data();
    }
}

键盘事件处理

Qt中的键盘事件通过QKeyEvent类实现。当键盘按键被按下或释放时,会触发键盘事件。

示例1:单个按键处理

widget.h中声明keyPressEvent()函数:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    
    // 声明按键按下事件
    void keyPressEvent(QKeyEvent* event);

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp中实现keyPressEvent()函数:

#include "widget.h"
#include "ui_widget.h"
#include <QKeyEvent>
#include <QDebug>

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

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

void Widget::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_A) {
        qDebug() << "A按键被按下";
    }
}

示例2:组合按键处理

void Widget::keyPressEvent(QKeyEvent *event)
{
    // 组合按键
    if(event->modifiers() == Qt::ControlModifier) // 判断是否按下ctrl键
    {
        if(event->key() == Qt::Key_A) {     // 判断 A 键是否按下
            qDebug() << "ctrl + A 被按下";
        }
    }
}

鼠标事件处理

鼠标单击事件

widget.h中声明mousePressEvent()函数:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    
    // 鼠标按下事件
    void mousePressEvent(QMouseEvent* event);

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

widget.cpp中实现mousePressEvent()函数:

#include "widget.h"
#include "ui_widget.h"
#include <QMouseEvent>
#include <QDebug>

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

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

void Widget::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton) {
        qDebug() << "鼠标左键被按下";
    }
}

鼠标释放事件

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

鼠标双击事件

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

鼠标移动事件

需要通过setMouseTracking(true)来启用鼠标追踪:

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

    // 设置鼠标追踪状态
    setMouseTracking(true);
}

void Widget::mouseMoveEvent(QMouseEvent *event)
{
    qDebug() << "[" << event->x() << ", " << event->y() << "]";
}

滚轮事件

#include <QWheelEvent>
void Widget::wheelEvent(QWheelEvent *event)
{
    static int x = 0;

    x += event->delta();   // ±120
    if(event->delta() > 0) {
        qDebug() << "滚轮往前" << x;
    }
    else {
        qDebug() << "滚轮往后" << x;
    }
}

本文详细介绍了Qt中事件处理的基本方法和具体实现,通过这些示例代码,读者可以快速掌握Qt事件处理的核心技巧,为开发功能丰富的Qt应用程序打下坚实的基础。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号