事件

本文深入探讨了Qt框架中的事件处理方式,包括重写`event`函数、`notify`函数以及事件的传递和接受。通过示例代码展示了如何处理键盘和鼠标事件,并解释了事件在对象间的传递流程。此外,还提到了子对象如何决定事件是否传递给父对象处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

事件处理方式

#include <QApplication>
#include<QWidget>
#include<QObject>
#include <iostream>
using namespace std;

class A:public QWidget{
public:
    bool event(QEvent* e); //事件处理方式 1:重写虚函数 QObject::event()
    void mousePressEvent(QMouseEvent* e);//事件处理方式 2:重写 QWidget 类中的此虚函数
};

bool A::event(QEvent* e){
    static int i=0; //i 用于计数
    cout<<"E"<<i++<<endl; //验证该函数能在事件到达目标对象之前被捕获
    if(e->type()==QEvent::KeyPress) //判断是否是键盘按下事件。
        cout<<"keyDwon"<<endl;
    return QWidget::event(e); /*此处应调用父类的 event 函数以对未处理的事件进行处理,若此处不
                                调用父类的 event,则本例 mousePressEvent 处理函数中的内容将不会
                                被执行*/
}

void A::mousePressEvent(QMouseEvent* e){//处理鼠标按下事件,这是 Qt 中最简单的事件处理方式。
    cout<<"mouseDwon"<<endl;
}

int main(int argc, char *argv[]){
    QApplication a(argc,argv); //在 Qt 中 QApplication 类型的对象只能有一个
    A ma; //创建一个部件
    ma.resize(333,222); //设置部件的大小
    ma.show(); //显示创建的部件
    a.exec(); //在此处进入事件主循环。
    return 0;
}

重写 notify 函数

#include <QApplication>
#include<QWidget>
#include<QObject>
#include <iostream>
using namespace std;

class A:public QWidget{
public:
    bool event(QEvent* e);//重写虚函数 QObject::event()
};

class AA:public QApplication{
public:
    AA(int i,char *p[]):QApplication(i,p){}
    bool notify(QObject *o,QEvent *e);//重写虚函数 notify
};

bool A::event(QEvent* e){
    cout<<"E"<<endl; //用于验证该函数是否被执行
    return QWidget::event(e);//应调用父类的 event 函数处理未处理的事件
}

bool AA::notify(QObject *o,QEvent *e){
    static int i=0;
    cout<<"N"<<i++<<endl;
    if(o->objectName()=="ma"&&e->type()==QEvent::KeyPress) //若对象为 ma 且事件为键盘按下事件
        cout<<"keyDwon"<<endl;
    return QApplication::notify(o,e); /*应调用父类的 notify 函数,否则本示例的 event 函数不会
                                        被执行,同时无法关闭窗口*/
}

int main(int argc, char *argv[]){
    AA aa(argc,argv);//在 Qt 中 QApplication 或其子类型的对象只能有一个
    A ma; //创建一个部件
    ma.setObjectName("ma"); //设置对象名,方便在 notify 函数中调用
    ma.resize(333,222); //设置部件的大小
    ma.show(); //显示创建的部件
    aa.exec();//在此处进入事件主循环。
    return 0;
}

前面我们已经验证过了event 函数先执行,然后具体的(比如mouseMoveEvent)后执行,这里我们验证notify函数先对事件进行处理,然后event函数再对事件进行处理!

事件传递

#include <QApplication>
#include<QWidget>
#include<QPushButton>
#include<QObject>
#include <iostream>
using namespace std;

class A:public QWidget{
public:
    bool event(QEvent* e);
};//子类化 QWidget

class C:public QPushButton{
public:
    bool event(QEvent* e);
}; //子类化标准按钮 QPushButton

bool A::event(QEvent* e){
    if(e->type()==QEvent::KeyPress) //判断是否是键盘按下事件。
    {
        cout<<objectName().toStdString()<<"=keyDwon"<<endl;
    }
    if(e->type()==QEvent::MouseButtonPress) //判断是否是鼠标按下事件。
    {
        cout<<objectName().toStdString()<<"=mouseDwon"<<endl;
    }
    if(e->type()==QEvent::MouseButtonRelease) //判断是否是鼠标释放事件。
    {
        cout<<objectName().toStdString()<<"=mouseRelease"<<endl;
    }
    return QWidget::event(e);
}

bool C::event(QEvent* e){
    if(e->type()==QEvent::KeyPress) //判断是否是键盘按下事件。
    {
        cout<<objectName().toStdString()<<"=keyDwon"<<endl;
        return 0; //将事件传递给父对象处理
    }
    if(e->type()==QEvent::MouseButtonPress) //判断是否是鼠标按下事件。
    {
        cout<<objectName().toStdString()<<"=mouseDwon"<<endl;
        return 1;//事件不传递
    }
    return QWidget::event(e);
}
int main(int argc, char *argv[]){
    QApplication a(argc,argv); //在 Qt 中 QApplication 类型的对象只能有一个
    A ma;
    C *mc=new C();
    mc->setParent(&ma); /*设置父对象为 ma,若 mc 未处理的对象会传递给此处设置的父对象 ma 处理,
                          注意事件传递是在对象之间的父子关系,而不是类之间的父子关系。*/
    mc->setText("AAA");
    mc->move(22,22); //设置 mc 相对于 ma 的位置
    ma.setObjectName("ma"); //设置对象名
    mc->setObjectName("mc");
    ma.resize(333,222); //设置部件的大小
    ma.show();
    a.exec(); //在此处进入事件主循环。
    return 0;
}

子对象处理函数中如果返回 0 ,就需要父对象相应函数来处理,如果返回 1 就不需要了!

子对象的 event 函数不处理了交给父对象的 event ,子对象的 mouseMoveEvent 不处理了交给父对象的 mouseMoveEvent!

事件的接受和忽略

 

event()函数与事件处理函数的关系

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sssnial-jz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值