Advertisement

Qt中的自定义事件

阅读量:

文章目录

    • 1 Qt中的自主发送事件
    • 2 发送系统预定义的事件
    • 3 发送自定义事件

1 Qt中的自主发送事件

Qt中可以在程序中自主发送事件:

  • 阻塞型事件发送:

    • 事件发送后需要等待事件处理完成。
  • 非阻塞型事件发送:

    • 事件发送后立即返回。
    • 事件被发送到事件队列中等待处理。

QApplication类提供了支持事件发送的静态成员函数:

  • 阻塞型发送函数:bool sendEvent(QObject* receiver, QEvent* event);
  • 非阻塞型发送函数:void postEvent(QObject* receiver, QEvent* event);

注意事项:

  • sendEvent中事件对象的生命周期由Qt程序管理:

    • 同时支持栈事件对象和堆事件对象的发送。
  • postEvent中事件对象的生命周期由Qt平台管理:

    • 只能发送堆事件对象。
    • 事件被处理后由Qt平台销毁。

使用sendEvent发送事件对象:
在这里插入图片描述
使用postEvent发送事件对象:
在这里插入图片描述


2 发送系统预定义的事件

示例代码如下:
Widget.h:

复制代码
    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QtGui/QWidget>
    #include <QPushButton>
    
    class Widget : public QWidget
    {
    Q_OBJECT
    
    QPushButton m_pushButton;
    
    void testSendEvent();
    void testPostEvent();
    protected slots:
    void onButtonClicked();
    public:
    Widget(QWidget *parent = 0);
    bool event(QEvent* evt);
    ~Widget();
    };
    
    #endif // WIDGET_H
    
    
    
    c
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-18/v1gxuyNE8V27pcFbniOGTZK6mak9.png)

Widget.cpp:

复制代码
    #include "Widget.h"
    #include <QMouseEvent>
    #include <QApplication>
    #include <QDebug>
    
    Widget::Widget(QWidget *parent)
    : QWidget(parent)
    {
    m_pushButton.setParent(this);
    m_pushButton.setText("Test");
    
    connect(&m_pushButton, SIGNAL(clicked()), this, SLOT(onButtonClicked()));
    }
    
    void Widget::onButtonClicked()
    {
    // testSendEvent();
    testPostEvent();
    }
    
    void Widget::testSendEvent()
    {
    QMouseEvent dbcEvt(QEvent::MouseButtonDblClick, QPoint(0, 0), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
    
    qDebug() << "Before sendEvent()";
    
    QApplication::sendEvent(this, &dbcEvt);
    
    qDebug() << "After sendEvent()";
    }
    
    void Widget::testPostEvent()
    {
    QMouseEvent* dbcEvt = new QMouseEvent(QEvent::MouseButtonDblClick, QPoint(0, 0), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
    
    qDebug() << "Before postEvent()";
    
    QApplication::postEvent(this, dbcEvt);
    
    qDebug() << "After postEvent()";
    }
    
    bool Widget::event(QEvent* evt)
    {
    if( evt->type() == QEvent::MouseButtonDblClick )
    {
        qDebug() << "event(): " << evt;
    }
    
    return QWidget::event(evt);
    }
    
    Widget::~Widget()
    {
    
    }
    
    
    
    c
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-18/vq4WFRiD1XdSZYnHMG6LtPw2mEoK.png)

main.cpp:

复制代码
    #include <QtGui/QApplication>
    #include "Widget.h"
    
    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    Widget w;
    w.show();
    
    return a.exec();
    }
    
    
    
    c
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-18/Dz6qVHbo1uiOl73xFAI28rmpe9Cj.png)

3 发送自定义事件

Qt可以自定义新的事件类:

  • 自定义事件类必须继承自QEvent。
  • 自定义的事件类必须拥有全局唯一的Type值。
  • 程序中必须提供处理自定义事件对象的方法。

自定义事件类:

  1. 将QEvent作为父类继承。
  2. 指定全局唯一的Type值。
    在这里插入图片描述

Qt事件的Type值:

  • 每个事件类都拥有全局唯一的Type值。
  • 自定义事件类的Type值也需要自定义。
  • 自定义事件类使用Qevent::User之后的值作为Type值。
  • 程序中保证QEvent::User + VALUE全局唯一即可。

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

  1. 将事件过滤器安装到目标对象:在eventFilter()函数中编写自定义事件的处理逻辑。
  2. 在目标对象的类中重写事件处理函数:在event()函数中编写自定义事件的处理逻辑。

为什么要自定义事件类?

  • 需要扩展一个已有组件类的功能。
  • 需要开发一个全新功能的组件类。
  • 需要像一个第三方的组件类发送消息。

示例代码如下:
StringEvent.h:

复制代码
    #ifndef _STRINGEVENT_H_
    #define _STRINGEVENT_H_
    
    #include <QEvent>
    #include <QString>
    
    class StringEvent : public QEvent
    {
    QString m_data;
    public:
    const static Type TYPE = static_cast<Type>(QEvent::User + 0xFF);
    
    explicit StringEvent(QString data = "");
    QString data();
    
    };
    
    #endif // _STRINGEVENT_H_
    
    
    
    c
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-18/kdeHJvxCQrSBMD13OmKzAEi420sb.png)

StringEvent.cpp:

复制代码
    #include "StringEvent.h"
    
    StringEvent::StringEvent(QString data) : QEvent(TYPE)
    {
    m_data = data;
    }
    
    QString StringEvent::data()
    {
    return m_data;
    }
    
    
    
    c
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-18/YEDNIwqCcir8OPZG4XsA7oJaV20K.png)

Widget.h:

复制代码
    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QtGui/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
    
    
    
    c
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-18/KCO6crA9JSZkie3p2LYTxu7IPoGz.png)

Widget.cpp:

复制代码
    #include "Widget.h"
    #include "StringEvent.h"
    #include <QMouseEvent>
    #include <QDebug>
    #include <QApplication>
    
    Widget::Widget(QWidget *parent)
    : QWidget(parent), m_edit(this)
    {
    m_edit.installEventFilter(this);
    }
    
    bool Widget::event(QEvent* evt)
    {
    if( evt->type() == QMouseEvent::MouseButtonDblClick )
    {
        qDebug() << "event: Before sentEvent";
    
        StringEvent e("D.T.Software");
    
        QApplication::sendEvent(&m_edit, &e);
    
        qDebug() << "event: After sentEvent";
    }
    
    return QWidget::event(evt);
    }
    
    bool Widget::eventFilter(QObject* obj, QEvent* evt)
    {
    if( (obj == &m_edit) && (evt->type() == StringEvent::TYPE) )
    {
        StringEvent* se = dynamic_cast<StringEvent*>(evt);
    
        qDebug() << "Receive: " << se->data();
    
        m_edit.insert(se->data());
    
        return true;
    }
    
    return QWidget::eventFilter(obj, evt);
    }
    
    Widget::~Widget()
    {
    
    }
    
    
    
    c
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-18/3sXQgiFdv9fIxN7KwAEuP4S5aGUr.png)

main.cpp:

复制代码
    #include <QtGui/QApplication>
    #include "Widget.h"
    
    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    Widget w;
    w.show();
    
    return a.exec();
    }
    
    
    
    c
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-18/vwAe4khrlBR3qZO8CEXyi1mGJxH9.png)

参考资料:

  1. QT实验分析教程

全部评论 (0)

还没有任何评论哟~