Qt 自定义event
- Qt 自定义event 推荐度:
- 相关推荐
Qt 自定义event
本文章从属于 Qt实验室-CSDN博客系列
自定义事件携带数据
在某些情况下,可能需要通过事件携带一些额外的数据
可以通过自定义事件类来完成
一种实现方法是自定义一个QObject的子类,通过property来携带数据
class MyEvent : public QObject,public QEvent
{Q_OBJECT
public:explicit MyEvent(QEvent::Type type,QObject *parent = nullptr);
}
这里通过一个自定义的窗口来发送自定义的事件,通过 QApplication::sendEvent(parent,evn);将事件传递给它的父窗口
MyWidget::MyWidget(QWidget *parent): QWidget{parent}
{QTimer* timer=new QTimer(this);timer->setInterval(1000);connect(timer,&QTimer::timeout,[=]{MyEvent* evn=new MyEvent(QEvent::Type(QEvent::User+101),this);evn->setProperty("x","1");evn->setProperty("y","2");//sendEvent阻塞式发送信号//发出去的信号需要接收者通过event()进行处理QApplication::sendEvent(parent,evn);
// QApplication::postEvent(parent,evn);});timer->start();
}
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{this->resize(500,300);MyWidget* center=new MyWidget(this);m_center=center;this->setCentralWidget(center);
}
在父窗口中通过event()去处理事件,并且获得事件中携带的数据
bool MainWindow::event(QEvent *event)
{if(event->type()==QEvent::Type(QEvent::User+101)){//需要dynamic_cast,qobject_cast会编译不过
// MyEvent* eve=qobject_cast<MyEvent*>(event);MyEvent* eve=dynamic_cast<MyEvent*>(event);qDebug()<<eve->property("x")<<","<<eve->property("y");qDebug()<<"in event :"<<"...";return true;}return true;
}
sendEvent阻塞式与postEvent队列式
这里,QApplication::sendEvent(parent,evn)后,会立刻进入MainWindow::event()中去进行处理;
而QApplication::postEvent(parent,evn);则是将事件放入队列后,立刻就返回了。
MyWidget::MyWidget(QWidget *parent): QWidget{parent}
{QTimer* timer=new QTimer(this);timer->setInterval(1000);connect(timer,&QTimer::timeout,[=]{MyEvent* evn=new MyEvent(QEvent::Type(QEvent::User+101),this);evn->setProperty("x","1");evn->setProperty("y","2");//sendEvent阻塞式发送信号//发出去的信号需要接收者通过event()进行处理
// QApplication::sendEvent(parent,evn);QApplication::postEvent(parent,evn);qDebug()<<"after send";});timer->start();
}
bool MainWindow::event(QEvent *event)
{if(event->type()==QEvent::Type(QEvent::User+101)){QThread::sleep(2);//需要dynamic_cast,qobject_cast会编译不过
// MyEvent* eve=qobject_cast<MyEvent*>(event);MyEvent* eve=dynamic_cast<MyEvent*>(event);
// QObject* eve=qobject_cast<QObject*>(event);qDebug()<<eve->property("x")<<","<<eve->property("y");qDebug()<<"in event :"<<"...";return true;}return false;
}
以上代码中,当使用 QApplication::sendEvent(parent,evn);时,打印的顺序是:
QVariant(QString, "1") , QVariant(QString, "2")
in event : ...
after send
当使用QApplication::postEvent(parent,evn);时,打印的顺序是:
after send
QVariant(QString, "1") , QVariant(QString, "2")
in event : ...
简单分析一下,当使用sendEvent发送事件时,会立刻进入到MainWindow::event(),从而打印QVariant(QString, "1") , QVariant(QString, "2")
in event : ...
从MainWindow::event()结束返回后,再回到QApplication::sendEvent()后面打印after send
体现了sendEvent的阻塞模式;
而使用postEvent发送事件时,会将事件放入队列,然后postEvent()返回了,于是打印了after send
等到事件队列处理了事件的时候,才会打印QVariant(QString, "1") , QVariant(QString, "2")
in event : ...
体现了postEvent的队列模式
但这里尽管发送事件的频率是1次/s,处理事件的频率是1次/2s,而使用postEvent发送事件时打印的after send和in event : ...依然是一一对应的。
这是因为发送事件和处理事件在同一个线程内,只有处理完了一个事件之后,timer才会继续下一个计时。
假如发送事件和处理事件不再同一个线程内,那么after send和in event : ...将不会一一对应。
- 解决脑蓝屏问题的五个方法
- 全面解析Typhoeus库编写的爬虫程序
- 【SpringBoot】序列化和反序列化介绍
- 2012年08月16日 Go生态洞察:优雅的代码组织之道
- Web后端开发
- 推动海洋经济高质量发展
- Actipro Software WinForms Controls 23.1.2
- XML Web 服务 Eclipse实现中的sun
- Pass基础
- nmap原理与使用
- Centos 7rc.local脚本命令开机不执行及指定用户启动的方法
- 【SpringBoot篇】使用Spring Cache高效处理缓存数据
- 【Seata源码学习 】 扫描@GlobalTransaction注解 篇一
- R语言编写代码示例
- 微信小程序授权登陆 getUserProfile
- nodejs+vue+python+PHP+微信小程序
- 深入理解Kafka3.6.0的核心概念,搭建与使用