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:
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() {}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(); }3 發送自定義事件
Qt可以自定義新的事件類:
- 自定義事件類必須繼承自QEvent。
- 自定義的事件類必須擁有全局唯一的Type值。
- 程序中必須提供處理自定義事件對象的方法。
自定義事件類:
Qt事件的Type值:
- 每個事件類都擁有全局唯一的Type值。
- 自定義事件類的Type值也需要自定義。
- 自定義事件類使用Qevent::User之后的值作為Type值。
- 程序中保證QEvent::User + VALUE全局唯一即可。
處理自定義事件對象的方法:
為什么要自定義事件類?
- 需要擴展一個已有組件類的功能。
- 需要開發一個全新功能的組件類。
- 需要像一個第三方的組件類發送消息。
示例代碼如下:
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 <QtGui/QWidget> #include <QLineEdit>class Widget : public QWidget {Q_OBJECTQLineEdit m_edit; public:Widget(QWidget *parent = 0);bool event(QEvent* evt);bool eventFilter(QObject* obj, QEvent* evt);~Widget(); };#endif // WIDGET_HWidget.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() {}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(); }參考資料:
總結
- 上一篇: 烤熟的红薯在烤箱加热要几分钟?
- 下一篇: 文本编辑器中菜单栏删除功能的实现