Qt中的自定义事件
发布日期:2021-07-01 04:26:04 浏览次数:3 分类:技术文章

本文共 4370 字,大约阅读时间需要 14 分钟。

文章目录

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 
#include
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

Widget.cpp:

#include "Widget.h"#include 
#include
#include
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 
#include "Widget.h"int main(int argc, char *argv[]){
QApplication a(argc, argv); Widget w; w.show(); return a.exec();}

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 
#include
class StringEvent : public QEvent{
QString m_data;public: const static Type TYPE = static_cast
(QEvent::User + 0xFF); explicit StringEvent(QString data = ""); 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 
#include
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 
#include
#include
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
(evt); qDebug() << "Receive: " << se->data(); m_edit.insert(se->data()); return true; } return QWidget::eventFilter(obj, evt);}Widget::~Widget(){
}

main.cpp:

#include 
#include "Widget.h"int main(int argc, char *argv[]){
QApplication a(argc, argv); Widget w; w.show(); return a.exec();}

参考资料:

转载地址:https://muzimin.blog.csdn.net/article/details/104991580 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:文本编辑器中菜单栏删除功能的实现
下一篇:文本编辑器实现光标定位的功能

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年04月27日 09时51分35秒