首页 > 代码库 > 第44课 发送自定义事件(下)

第44课 发送自定义事件(下)

1. 自定义事件对象

(1)自定义事件类必须继承自QEvent

(2)自定义的事件类必须拥有全局唯一的Type值

(3)程序中必须提供处理自定义事件对象的方法

2. 自定义事件类

(1)将QEvent作为父类继承

(2)指定全局唯一的Type值

class StringEvent: public QEvent
{
public:
    //提供全局唯一的Type值
    static const Type TYPE = static_cast<Type>(QEvent::User + 0xFF);
    
    //...
};

(3)Qt事件的Type值

  ①每个事件类都拥有全局唯一的Type值

  ②自定义事件类的Type值也需要自定义。

  ③自定义事件类使用QEvent::User之后的值作为Type值

  ④程序中保证QEvent::User + VALUE全局唯一即可。

3. 处理自定义事件对象的方法

(1)方法1:将事件过滤器安装到目标对象,然后在eventFilter()数中编写自定义事件的处理逻辑

(2)方法2:在目标对象的类中重写事件处理函数,即在event()函数中编写自定义事件的处理逻辑。

【编程实验】发送和处理自定义事件(方法1)

//main.cpp

#include "Widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

//StringEvent.h

#ifndef _STRINGEVENT_H_
#define _STRINGEVENT_H_

#include <QEvent>
#include <QString>

//自定义事件类必须继承自QEvent
class StringEvent : public QEvent
{
    QString m_data;
public:

    //必须提供事件类的Type值
    static const Type TYPE = static_cast<Type>(QEvent::User + 0xFF);

    explicit StringEvent(QString data = http://www.mamicode.com/"");
    QString data();
};

#endif // _STRINGEVENT_H_

//StringEvent.cpp

#include "StringEvent.h"

StringEvent::StringEvent(QString data):QEvent(TYPE)
{
    m_data = data;
}

QString StringEvent::data()
{
    return m_data;
}

//Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QLineEdit>

class Widget : public QWidget
{
    Q_OBJECT

    QLineEdit m_edit;

public:
    Widget(QWidget *parent = 0);
    bool event(QEvent* evt);
    bool eventFilter(QObject* obj, QEvent* evt);

    ~Widget();
};

#endif // WIDGET_H

//Widget.cpp

#include "Widget.h"
#include "StringEvent.h"
#include <QApplication>
#include <QMouseEvent>
#include <qDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent),m_edit(this)
{
    //为m_edit安装事件过滤器,将发往m_edit的事件先交给this的eventFilter处理
    m_edit.installEventFilter(this);
}

//发送自定义事件对象(当鼠标双击窗口时)。
bool Widget::event(QEvent* evt)
{
    if(evt->type() == QMouseEvent::MouseButtonDblClick)
    {
        qDebug() << "event: Before sentEvent";

        StringEvent se("SantaClaus"); //发送自定义事件对象

        QApplication::sendEvent(&m_edit, &se);//将事件对象发送给编辑框

        qDebug() << "event: After sendEvent";

    }
    return QWidget::event(evt);
}

//采用方法1:自定义事件的处理,通过eventFilter编写自定义事件的处理逻辑
bool Widget::eventFilter(QObject *obj, QEvent *evt)
{
    if((obj == &m_edit) && (evt->type() == StringEvent::TYPE))
    {
        StringEvent* se = dynamic_cast<StringEvent*>(evt);
        m_edit.insert(se->data());
        qDebug() <<"Receive: " << se->data();
        return true;
    }
    return QWidget::eventFilter(obj, evt);
}


Widget::~Widget()
{

}

4. 为什么要自定义事件类?

(1)需要扩展一个己有组件类的功能

(2)需要开发一个全新功能的组件类

(3)需要向一个第3方的组件类发送消息

(4)……

5. 小结

(1)自定义事件类必须继承自QEvent

(2)自定义事件类使用QEvent::User之后的值作为Type值

(3)自定义事件类的Type值必须全局唯一

(4)程序中需要提供自定义事件类的处理方法

 

第44课 发送自定义事件(下)