Qt事件处理机制_鼠标事件_键盘事件

前置小知识

事件:由程序内部或者外部,产生的事件或者产生的某个动作(事件 是一个不同步或者说是一个异步的过程,可以由不同对象产生)

信号:是一个同步的过程,只要们点击了/按下了,触发了信号之后,那么槽函数就会进行响应(帮定发送对象和接收对象)

事件举例:

  • 鼠标事件
    • 按下事件
    • 释放事件
    • 移动事件
    • 双击事件

Qt定时器事件

实现方法一(不建议这么使用)

eventwidget.h

// 需要在头文件中创建id, 实现 timerEvent 方法
public:
virtual void timerEvent(QTimerEvent*event);
private:
int id; // 在publi里面也可以
int id_1;

eventwidget.cpp

// 需要在默认构造中添加定时 Begin
// startTimer属于Object 设置定时间隔2秒, id定时器的标识符
id = this->startTimer(2000);
id_1 = this->startTimer(500); // 对比方便观察
/**
 * @brief 定时器事件
 * @param event
 */
void EventWidget::timerEvent(QTimerEvent *event) {
    static int i = 0, j = 0;
    if(event->timerId() == id) {
        ui->label->setNum(++i);

        // 判断定时器是否达到10秒的时间,如果达成则停止工作
        if(i == 5) {
            //停止计时->因为没个id都不同所以下面不会有影响
            this->killTimer(id);
        }
    }
    if(event->timerId() == id_1) {
        ui->label_2->setNum(++j);
    }
}

实现方法二

对于QTimer我们还是比较常用的,可能会在很多项目当中看到,并方便我们做一些移植的工作

// 头文件
#include <QTimer>
// QTimer 实现定时器功能
QTimer *timer = new QTimer(this);
static int index = 0;
connect(timer, &QTimer::timeout, this, [=](){
	ui->label_3->setNum(++index);
	if(index == 10) timer->stop(); // 到10就停止
});
timer->start(500);

Qt鼠标事件

// 头文件
#include <QMouseEvent>
// 声明虚函数_鼠标事件
virtual void mousePressEvent(QMouseEvent *event);
// 鼠标事件,按下、释放、双击、移动
/**
 * @brief 鼠标事件(按下(QWidget::mousePressEvent()),释放(QWidget::mouseReleaseEvent()),双击(QWidget::mouseDoubleClickEvent()))
 * @param event
 */
void EventWidget::mousePressEvent(QMouseEvent *event) {
    // 左键
    if(event->button() == Qt::LeftButton) {
        // x 代表应用程序左上角起始位置的值, %1 - %2代表有两个参数
        ui->label->setText(QString("x : %1, y = %2").arg(event->x()).arg(event->y()));
    }
    // 右键
    else if(event->button() == Qt::RightButton) {
        // 以整个窗口左上角为原点的坐标系
        ui->label_3->setText(QString("x : %1, y = %2").arg(event->globalX()).arg(event->globalY()));
    }
    // 中键
    else if(event->button() == Qt::MiddleButton) {
        ui->label_4->setText("按下鼠标中建");
    }
}

image-20230711191656749

Qt键盘事件

使用 QWidget 里面自带的 keyPressEvent 函数来完成对按键的响应。

使用用中可能出现的问题

  1. 某段程序使用重载 keyPressEvent 后发现不能接收到键盘的响应。

    解决办法一:Qt文档曾说明 需要类的构造函数中需要写上 setFocusPolicy(Qt::StrongFocus);

​ 解决办法二:替换掉 keyPressEvent 重载 keyReleaseEvent 进行测试

/**
 * @brief 按键事件
 * @param event
 */
// 使用 keyPressEvent 捕获不到键盘可以使用 keyReleaseEvent
void EventWidget::keyPressEvent(QKeyEvent *event) {

    // 某单一按键按下
    if(event->key() == Qt::Key_F) {
        qDebug() << "以按下F";
    } else if(event->key() == Qt::Key_G) {
        qDebug() << "以按下G";
        // 先按G在按0以这样的方法设置组合按键是不可行的,也不会触发
        if(event->key() == Qt::Key_0) {
            qDebug() << "以按下G + 0";
        }
    }

    /*
        ConstantValueDescription
        Qt::NoModifier          0x00000000No    modifier key is pressed.
        Qt::ShiftModifier       0x02000000A     Shift key on the keyboard is pressed.
        Qt::ControlModifier     0x04000000A     Ctrl key on the keyboard is pressed.
        Qt::AltModifier         0x08000000An    Alt key on the keyboard is pressed.
        Qt::MetaModifier        0x10000000A     Meta key on the keyboard is pressed.
        Qt::KeypadModifier      0x20000000A     keypad button is pressed.
        Qt::GroupSwitchModifier 0x40000000X11   only (unless activated on Windows by a command line argument). A Mode_switch key on the keyboard is pressed.
    */
    // 组合按键按下Ctrl + F
    if(event->modifiers() == Qt::ControlModifier) {
        if(event->key() == Qt::Key_F) {
            qDebug() << "Ctrl + F 按键被按下";
        }
    }

    else qDebug() << "按键响应测试";
}

Ps:在单一按键按下,里面嵌套另一个单一按键想设置成组合按键这是不可行的(代码如下)

if(event->key() == Qt::Key_G) {
	qDebug() << "以按下G";
	// 先按G在按0以这样的方法设置组合按键是不可行的,也不会触发
	if(event->key() == Qt::Key_0) {
		qDebug() << "以按下G + 0";
	}
}

代码合集

evntwidget.h

#ifndef EVENTWIDGET_H
#define EVENTWIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class EventWidget; }
QT_END_NAMESPACE

class EventWidget : public QWidget
{
    Q_OBJECT

public:
    EventWidget(QWidget *parent = nullptr);
    ~EventWidget();

protected:
// 时钟事件
virtual void timerEvent(QTimerEvent*event);
// 鼠标事件
virtual void mousePressEvent(QMouseEvent *event);
// 键盘事件
virtual void keyPressEvent(QKeyEvent *event);


private:
    Ui::EventWidget *ui;
    int id, id_1;

};
#endif // EVENTWIDGET_H

evntwidget.cpp

#include "eventwidget.h"
#include "ui_eventwidget.h"

#include <QTimer>

#include <QDebug>

#include <QMouseEvent>
#include <QKeyEvent>

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

    // startTimer属于Object 设置定时间隔2秒, id定时器的标识符
    id = this->startTimer(2000);
//    id_1 = this->startTimer(500);

    // QTimer 实现定时器功能
    QTimer *timer = new QTimer(this);
    static int index = 0;
    connect(timer, &QTimer::timeout, this, [=](){
        ui->label_3->setNum(++index);
        if(index == 10) timer->stop(); // 到10就停止
    });
    timer->start(500);

// setFocusPolicy(Qt::StrongFocus);
        
}

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

/**
 * @brief 定时器事件
 * @param event
 */
void EventWidget::timerEvent(QTimerEvent *event) {
    static int i = 0, j = 0;
    if(event->timerId() == id) {
        ui->label->setNum(++i);

        // 判断定时器是否达到10秒的时间,如果达成则停止工作
        if(i == 5) {
            //停止计时
            this->killTimer(id);
        }
    }
    if(event->timerId() == id_1) {
        ui->label_2->setNum(++j);
    }
}


// 鼠标事件,按下、释放、双击、移动
/**
 * @brief 鼠标事件(按下(QWidget::mousePressEvent()),释放(QWidget::mouseReleaseEvent()),双击(QWidget::mouseDoubleClickEvent()))
 * @param event
 */
void EventWidget::mousePressEvent(QMouseEvent *event) {
    // 左键
    if(event->button() == Qt::LeftButton) {
        // x 代表应用程序左上角起始位置的值, %1 - %2代表有两个参数
        ui->label->setText(QString("x : %1, y = %2").arg(event->x()).arg(event->y()));
    }
    // 右键
    else if(event->button() == Qt::RightButton) {
        // 以整个窗口左上角为原点的坐标系
        ui->label_3->setText(QString("x : %1, y = %2").arg(event->globalX()).arg(event->globalY()));
    }
    // 中键
    else if(event->button() == Qt::MiddleButton) {
        ui->label_4->setText("按下鼠标中建");
    }
}

/**
 * @brief 按键事件
 * @param event
 */
// 使用 keyPressEvent 捕获不到键盘可以使用 keyReleaseEvent
void EventWidget::keyPressEvent(QKeyEvent *event) {

    // 某单一按键按下
    if(event->key() == Qt::Key_F) {
        qDebug() << "以按下F";
    } else if(event->key() == Qt::Key_G) {
        qDebug() << "以按下G";
        // 先按G在按0以这样的方法设置组合按键是不可行的,也不会触发
        if(event->key() == Qt::Key_0) {
            qDebug() << "以按下G + 0";
        }
    }

    /*
        ConstantValueDescription
        Qt::NoModifier          0x00000000No    modifier key is pressed.
        Qt::ShiftModifier       0x02000000A     Shift key on the keyboard is pressed.
        Qt::ControlModifier     0x04000000A     Ctrl key on the keyboard is pressed.
        Qt::AltModifier         0x08000000An    Alt key on the keyboard is pressed.
        Qt::MetaModifier        0x10000000A     Meta key on the keyboard is pressed.
        Qt::KeypadModifier      0x20000000A     keypad button is pressed.
        Qt::GroupSwitchModifier 0x40000000X11   only (unless activated on Windows by a command line argument). A Mode_switch key on the keyboard is pressed.
    */
    // 组合按键按下Ctrl + F
    if(event->modifiers() == Qt::ControlModifier) {
        if(event->key() == Qt::Key_F) {
            qDebug() << "Ctrl + F 按键被按下";
        }
    }
    else qDebug() << "按键响应测试";
}

image-20230712104248083

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值