Qt——Qt中的事件处理(一)

1.图形界面应用程序的消息处理模型:

用户进行用户操作后,操作系统内核先感知到,然后传递系统消息,调用操作系统中应用程序的消息处理函数,对系统消息进行处理。

2.Qt平台将系统产生的消息转换为Qt事件

  • Qt事件是一个QEvent对象
  • Qt事件用于描述程序内部或外部发生的动作
  • 任意的QObject对象都具备事件处理的能力

3.GUI应用程序的事件处理方式

  • Qt事件产生后立即被分发到QWidget对象
  • QWidget中的event(QEvent*)进行事件处理
  • event()根据事件类型调用不同的事件处理函数
  • 在事件处理函数中发送Qt中预定义的信号
  • 调用信号关联的槽函数

流程:

用户点击按钮被操作系统所感知到------>操作系统在内部发送一条点击的系统消息到当前的应用程序上------>转换为Qt的事件分发到用户点击的按钮上------>按钮调用自身的event()函数------>按钮调用click()函数------>按钮发送一个QT的点击信号到其他的Qt对象上------>调用对应槽函数

QMyPushButton.h

复制代码
#ifndef QMYPUSHBUTTON_H
#define QMYPUSHBUTTON_H

#include <QObject>
#include <QPushButton>

//定义一个函数类型
typedef void (*QButtonListener) (QObject*, QMouseEvent*);

class QMyPushButton : public QPushButton
{
    Q_OBJECT

protected:
    QButtonListener m_listener; //m_listener用于存储回调函数的地址
    void mouseReleaseEvent(QMouseEvent* e); //重写了父类 QPushButton 的鼠标释放事件处理函数,当鼠标释放时会自动调用

public:
    QMyPushButton(QWidget* parent = 0, QButtonListener m_listener = 0);
protected slots:

};

#endif // QMYPUSHBUTTON_H

QMyPushButton.cpp

复制代码
#include "QMyPushButton.h"
#include <QMouseEvent>
#include <QDebug>
QMyPushButton::QMyPushButton(QWidget* parent, QButtonListener listener) : QPushButton(parent)
{
    m_listener = listener;
    setMouseTracking(true);
} 

void QMyPushButton::mouseReleaseEvent(QMouseEvent* e)
{
    qDebug()<<"mouseReleaseEvent"<<e;
    // 检查回调函数是否有效
    if( m_listener != NULL )
    {
        m_listener(this, e); // 调用回调函数,传递按钮自身和事件信息
        e->accept(); // 表示事件已处理
        setDown(false);      // 手动设置为未按下状态
    }
    else
    {
        QPushButton::mouseReleaseEvent(e); // 没有回调时使用默认处理
    }

}

Widget.h

复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "QMyPushButton.h"

class Widget : public QWidget
{
    Q_OBJECT

    QMyPushButton myButton;
protected slots:
    void onMyButtonClicked();
public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget() override;
};
#endif // WIDGET_H

Widget.cpp

复制代码
#include "Widget.h"
#include <QDebug>

void onMyButtonRelease(QObject* sender, QMouseEvent* e)
{
    qDebug() << "onMyButtonRelease(QObject* sender, QMouseEvent* e)";

    // 埋点处理
}
Widget::Widget(QWidget *parent) : QWidget(parent), myButton(this, &onMyButtonRelease)
{
    myButton.setText("QMyPushButton");
    connect(&myButton, SIGNAL(clicked()), this, SLOT(onMyButtonClicked()));
}
void Widget::onMyButtonClicked()
{
    qDebug() << "onMyButtonClicked()";
}
Widget::~Widget() = default;

4.事件和信号不同

  • 事件由具体对象进行处理,信号由具体对象主动产生
  • 改写事件处理函数可能导致程序行为发生改变
  • 信号是否存在对应的槽函数不会改变程序行为
  • 一般而言,信号在具体的事件处理函数中产生
相关推荐
爱吃牛肉的大老虎1 小时前
rust基础之环境搭建
java·开发语言·rust
openKylin1 小时前
与全球技术演进同频,openKylin 3.0从C迈向Rust
c语言·开发语言·rust·开源·开放原子·openkylin
疯狂打码的少年2 小时前
【软件工程】结构化设计:模块独立性与耦合内聚
java·开发语言·笔记·软件工程
程高兴2 小时前
PMSM基于在线转动惯量辩识的滑模负载转矩观测器MATLAB-SIMULINK仿真模型
开发语言·matlab
kisloy2 小时前
【python零基础教程第24讲】代码规范与质量管控
开发语言·python
C++、Java和Python的菜鸟3 小时前
第4章 后端Web基础(基础知识)
java·开发语言
芷栀夏3 小时前
Java教育平台实战复盘:课程、考试与学习行为分析系统设计
java·开发语言·学习
从零开始的代码生活_3 小时前
C++ 多态详解:虚函数、动态绑定、抽象类与虚表原理
开发语言·c++·后端·学习·算法
xywww1683 小时前
AWS 账号权限怎么分:根用户和 IAM 用户区别及日常使用建议
大数据·开发语言·人工智能·python·gpt·云计算·aws
大彼方..3 小时前
C++ STL Vector 深度剖析:从内存管理到性能优化
开发语言·c++