• Qt 自定义event


    本文章从属于  Qt实验室-CSDN博客系列

    自定义事件携带数据

    在某些情况下,可能需要通过事件携带一些额外的数据

    可以通过自定义事件类来完成

    一种实现方法是自定义一个QObject的子类,通过property来携带数据

    1. class MyEvent : public QObject,public QEvent
    2. {
    3. Q_OBJECT
    4. public:
    5. explicit MyEvent(QEvent::Type type,QObject *parent = nullptr);
    6. }

    这里通过一个自定义的窗口来发送自定义的事件,通过 QApplication::sendEvent(parent,evn);将事件传递给它的父窗口

    1. MyWidget::MyWidget(QWidget *parent)
    2. : QWidget{parent}
    3. {
    4. QTimer* timer=new QTimer(this);
    5. timer->setInterval(1000);
    6. connect(timer,&QTimer::timeout,[=]{
    7. MyEvent* evn=new MyEvent(QEvent::Type(QEvent::User+101),this);
    8. evn->setProperty("x","1");
    9. evn->setProperty("y","2");
    10. //sendEvent阻塞式发送信号
    11. //发出去的信号需要接收者通过event()进行处理
    12. QApplication::sendEvent(parent,evn);
    13. // QApplication::postEvent(parent,evn);
    14. });
    15. timer->start();
    16. }
    1. MainWindow::MainWindow(QWidget *parent)
    2. : QMainWindow(parent)
    3. {
    4. this->resize(500,300);
    5. MyWidget* center=new MyWidget(this);
    6. m_center=center;
    7. this->setCentralWidget(center);
    8. }

    在父窗口中通过event()去处理事件,并且获得事件中携带的数据 

    1. bool MainWindow::event(QEvent *event)
    2. {
    3. if(event->type()==QEvent::Type(QEvent::User+101))
    4. {
    5. //需要dynamic_cast,qobject_cast会编译不过
    6. // MyEvent* eve=qobject_cast<MyEvent*>(event);
    7. MyEvent* eve=dynamic_cast<MyEvent*>(event);
    8. qDebug()<<eve->property("x")<<","<<eve->property("y");
    9. qDebug()<<"in event :"<<"...";
    10. return true;
    11. }
    12. return true;
    13. }

    sendEvent阻塞式与postEvent队列式

    这里,QApplication::sendEvent(parent,evn)后,会立刻进入MainWindow::event()中去进行处理;

    QApplication::postEvent(parent,evn);则是将事件放入队列后,立刻就返回了

    1. MyWidget::MyWidget(QWidget *parent)
    2. : QWidget{parent}
    3. {
    4. QTimer* timer=new QTimer(this);
    5. timer->setInterval(1000);
    6. connect(timer,&QTimer::timeout,[=]{
    7. MyEvent* evn=new MyEvent(QEvent::Type(QEvent::User+101),this);
    8. evn->setProperty("x","1");
    9. evn->setProperty("y","2");
    10. //sendEvent阻塞式发送信号
    11. //发出去的信号需要接收者通过event()进行处理
    12. // QApplication::sendEvent(parent,evn);
    13. QApplication::postEvent(parent,evn);
    14. qDebug()<<"after send";
    15. });
    16. timer->start();
    17. }
    1. bool MainWindow::event(QEvent *event)
    2. {
    3. if(event->type()==QEvent::Type(QEvent::User+101))
    4. {
    5. QThread::sleep(2);
    6. //需要dynamic_cast,qobject_cast会编译不过
    7. // MyEvent* eve=qobject_cast<MyEvent*>(event);
    8. MyEvent* eve=dynamic_cast<MyEvent*>(event);
    9. // QObject* eve=qobject_cast<QObject*>(event);
    10. qDebug()<<eve->property("x")<<","<<eve->property("y");
    11. qDebug()<<"in event :"<<"...";
    12. return true;
    13. }
    14. return false;
    15. }

    以上代码中,当使用 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 : ...将不会一一对应。

  • 相关阅读:
    ATC:一个能将主流开源框架模型转换为昇腾模型的神奇工具
    STM32的四种开发方式
    java spring cloud 企业电子招标采购系统源码:营造全面规范安全的电子招投标环境,促进招投标市场健康可持续发展
    【Java基础系列】Java中的关键字
    vue.mixin全局混合选项
    「C系列」C 数据类型
    2021CSP入门级第一轮认证详细解析
    [pwn基础]Linux安全机制
    AcWing 799. 最长连续不重复子序列——算法基础课题解
    四、Flask进阶
  • 原文地址:https://blog.csdn.net/xiyangxiaoguo/article/details/134376172