Qt5.9学习笔记-事件(二) 自定义事件

news2024/11/19 5:17:49

⭐️我叫忆_恒心,一名喜欢书写博客的在读研究生👨‍🎓。
如果觉得本文能帮到您,麻烦点个赞👍呗!

近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧,喜欢的小伙伴给个三连支持一下呗。👍⭐️❤️
Qt5.9专栏定期更新Qt的一些项目Demo
项目与比赛专栏定期更新比赛的一些心得面试项目常被问到的知识点。

QT5.9专栏会定期更新有趣的Qt知识

以工程为导向进行Qt5.9的学习,打捞基础。专栏中有Qt5.9学习笔记-仿Everything的的文件搜索的GUI工具,以及相关的基础知识。
在这里插入图片描述

最近在重新梳理一下Qt事件的基础知识,发现了一些有趣的知识点和开发的坑点,做一些笔记。

当涉及到Qt5.9事件时,事件系统是非常重要的一个主题。Qt5.9事件系统是一个强大的工具,它允许开发人员在Qt应用程序中响应和处理各种类型的事件。在本文中,我们将讨论Qt5.9事件系统的基础知识以及如何在应用程序中使用它来处理事件。

目录

    • 3 自定义事件
      • 3.1 创建自定义事件
      • 3.2 发送和处理自定义事件
      • 3.3 使用自定义事件来扩展Qt应用程序
      • :fire:3.4 坑点的地方要注意一下:

3 自定义事件

3.1 创建自定义事件

在Qt5.9中,可以使用QEvent::registerEventType()函数来注册自定义事件类型。注册自定义事件类型时,需要

  • 创建自定义事件

创建自定义事件:
在Qt中,可以通过继承QEvent类来创建自定义事件。我们需要定义一个新的事件类型,并在该事件类型中添加需要的数据。下面是一个简单的例子来说明如何创建自定义事件:

#include <QEvent>

class MyCustomEvent : public QEvent
{
public:
    static constexpr QEvent::Type EventType = static_cast<QEvent::Type>(QEvent::User + 1);

    MyCustomEvent(const QString &data) : QEvent(EventType), m_data(data) {}

    QString data() const { return m_data; }

private:
    QString m_data;
};

在上面的代码中,我们定义了一个名为MyCustomEvent的自定义事件。我们通过继承QEvent类来创建该事件,并在事件类型中添加了一个QString类型的数据。注意,我们需要为该事件定义一个唯一的事件类型。在本例中,我们将事件类型设置为QEvent::User + 1。

3.2 发送和处理自定义事件

我们可以通过QCoreApplication::postEvent()函数来发送自定义事件。该函数会将自定义事件插入到事件队列中,然后返回。当事件队列中有自定义事件时,事件分发机制会将其分发到正确的QObject派生类对象中进行处理。下面是一个简单的例子来说明如何发送和处理自定义事件:

#include <QCoreApplication>
#include <QDebug>

class MyObject : public QObject
{
public:
    MyObject(QObject *parent = nullptr) : QObject(parent) {}

protected:
    bool event(QEvent *event) override
    {
        if (event->type() == MyCustomEvent::EventType) {
            MyCustomEvent *customEvent = static_cast<MyCustomEvent *>(event);
            qDebug() << "Received custom event with data:" << customEvent->data();
            return true;
        }
        return QObject::event(event);
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);

    MyObject obj;
    obj.setObjectName("myObject");

    QCoreApplication::postEvent(&obj, new MyCustomEvent("Hello, world!"));

    return app.exec();
}

在上面的代码中,我们定义了一个名为MyObject的QObject派生类对象,并在其中重载了event()函数来处理自定义事件。当收到自定义事件时,我们将其转换为MyCustomEvent类型,并打印出事件中存储的数据。在main()函数中,我们创建了一个MyObject对象,并使用QCoreApplication::postEvent()函数来向该对象发送一个自定义事件。

3.3 使用自定义事件来扩展Qt应用程序

自定义事件可以帮助我们扩展Qt应用程序的功能。例如,我们可以定义一个自定义事件来实现异步任务。在任务完成后,我们可以发送自定义事件来通知应用程序更新界面。下面是一个简单的例子来说明如何使用自定义事件来扩展Qt应用程序:

#include <QCoreApplication>
#include <QDebug>
#include <QThread>
#include <QTimer>

class MyObject : public QObject
{
public:
    MyObject(QObject *parent = nullptr) : QObject(parent) {}

    void startTask()
    {
        QThread *thread = new QThread(this);
        Worker *worker = new Worker();
        worker->moveToThread(thread);

        connect(thread, &QThread::started, worker, &Worker::doWork);
        connect(worker, &Worker::workFinished, this, &MyObject::onWorkFinished);
        connect(worker, &Worker::finished, thread, &QThread::quit);
        connect(worker, &Worker::finished, worker, &Worker::deleteLater);
        connect(thread, &QThread::finished, thread, &QThread::deleteLater);

        thread->start();
    }

signals:
    void taskFinished(const QString &result);

private slots:
    void onWorkFinished(const QString &result)
    {
        QCoreApplication::postEvent(this, new TaskFinishedEvent(result));
    }
};

class Worker : public QObject
{
public:
    Worker(QObject *parent = nullptr) : QObject(parent) {}

signals:
    void workFinished(const QString &result);
    void finished();

public slots:
    void doWork()
    {
        qDebug() << "Starting task on thread:" << QThread::currentThread();
        QThread::sleep(5);
        emit workFinished("Task finished successfully!");
        emit finished();
    }
};

class TaskFinishedEvent : public QEvent
{
public:
    static constexpr QEvent::Type EventType = static_cast<QEvent::Type>(QEvent::User + 1);

    TaskFinishedEvent(const QString &result) : QEvent(EventType), m_result(result) {}

    QString result() const { return m_result; }

private:
    QString m_result;
};

class MyApplication : public QCoreApplication
{
public:
    MyApplication(int argc, char **argv) : QCoreApplication(argc, argv)
    {
        m_object.setObjectName("myObject");
        m_object.startTask();
    }

protected:
    bool event(QEvent *event) override
    {
        if (event->type() == TaskFinishedEvent::EventType) {
            TaskFinishedEvent *taskFinishedEvent = static_cast<TaskFinishedEvent *>(event);
            qDebug() << "Task finished with result:" << taskFinishedEvent->result();
            quit();
            return true;
        }
        return QCoreApplication::event(event);
    }

private:
    MyObject m_object;
};

int main(int argc, char *argv[])
{
    MyApplication app(argc, argv);
    return app.exec();
}

在上面的代码中,我们定义了一个名为MyObject的QObject派生类对象,并在其中定义了一个名为startTask()的槽函数。该槽函数会创建一个新的QThread对象,并将一个名为Worker的QObject派生类对象移动到该线程中。然后,我们通过信号和槽来连接。

🔥3.4 坑点的地方要注意一下:

自定义按钮事件的时候,进行重写的时候,最好要调用父类的方法进行重写

问题 : 槽函数没有响应?

image-20230425224452667

否则的话,要对一些信号的处理做一些额外工作,否则槽函数可能调用不了

// 以下是一个简单的示例程序,演示了如何解决槽函数没有相应的问题:

#include <QApplication>
#include <QPushButton>

class MyButton : public QPushButton
{
    Q_OBJECT

public:
    MyButton(QWidget *parent = nullptr) : QPushButton(parent) {}

protected:
    void mousePressEvent(QMouseEvent *event) override {
        QPushButton::mousePressEvent(event);
        emit clicked(event->x(), event->y());
    }

signals:
    void clicked(int x, int y);
};

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr) : QWidget(parent) {
        button = new MyButton(this);
        button->setText("Click me");
        button->move(50, 50);

        connect(button, &MyButton::clicked, this, &Widget::onButtonClicked);
    }

private slots:
    void onButtonClicked(int x, int y) {
        qDebug("Button clicked at (%d, %d)", x, y);
    }

private:
    MyButton *button;
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    Widget widget;
    widget.show();

    return app.exec();
}

在上面的示例中,我们自定义了一个 MyButton 类继承自 QPushButton,重载了 mousePressEvent() 函数来处理鼠标点击事件,并通过 emit 语句发送了 clicked 信号,传递了鼠标点击位置的坐标。在 Widget 类中,我们实例化了 MyButton 对象,并将其与 onButtonClicked() 槽函数绑定。当鼠标点击按钮时,槽函数会被调用,并输出鼠标点击位置的坐标。

最后,最后
如果觉得有用,麻烦三连👍⭐️❤️支持一下呀,希望这篇文章可以帮到你,你的点赞是我持续更新的动力

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/491965.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法设计与智能计算 || 专题八: 拉普拉斯算子与图拉普拉斯

拉普拉斯算子与图拉普拉斯 文章目录 拉普拉斯算子与图拉普拉斯1. 拉普拉斯基本概念与计算1.1 哈密尔顿算子1.2 梯度(gradient)1.3 散度(divergence)1.4 拉普拉斯算子 2. 图像或图上的拉普拉斯算子2.1 离散网格上的拉普拉斯算子2.2 图(graph)上的拉普拉斯算子2.2.1 图的梯度(考虑…

云时通助力耐消品行业经销商数字化管理,全面破除渠道管理难题

随着中国商业正在从“消费红利”经济向“数智创新”经济进化&#xff0c;耐用消费品零售发展思路从单节点成本和效率提升&#xff0c;向数字技术触发的全链路数智化转型。如何顺利从“传统分销模型”向“零售模式”转型成为企业关注重点问题。 耐消品作为典型的长链条交易&…

人生不能重来,于是有了电影

人生不能重来&#xff0c;于是有了电影&#x1f3ac;&#xff0c;2020年对于我来说是特殊的年份&#xff0c;由于疫情公司受到严重打击&#xff0c;我所属的行业与我背道而驰&#xff0c;就这样&#xff0c;我失业了&#xff0c;从没想过&#xff0c;会因为这个原因而离开一家自…

机器学习之朴素贝叶斯一

一、概述 朴素贝叶斯算法是典型的有监督学习算法&#xff0c;解决的是分类问题 贝叶斯算法是一种基于贝叶斯定理的分类算法&#xff0c;它的优点和缺点如下&#xff1a; 优点&#xff1a; 算法原理简单易懂&#xff0c;实现较为容易&#xff1b;可以利用先验知识对模型进行训…

2.0 Vue框架设计的核心要素

本章主要讲解&#xff0c;一个好的框架在构建的时候&#xff0c;需要考虑到的要素&#xff0c;包含报错信息反馈、警告信息反馈、减少打包体积、良好的输出、特性开关&#xff08;兼容&#xff09;等 1、提升用户开发体验 提升用户开发体验主要体现在用户使用框架进行开发时&…

3DES实验 思考与练习:

T1&#xff1a;关于3DES的分析 和 库函数的思考——完全领悟了&#xff01;&#xff01;&#xff01; #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/des.h> /***********************************************…

java小记

public class Test {/*** 谓类的方法就是指类中用static 修饰的方法&#xff08;非static 为实例方法&#xff09;&#xff0c;比如main 方法&#xff0c;那么可以以main* 方法为例&#xff0c;可直接调用其他类方法&#xff0c;必须通过实例调用实例方法&#xff0c;this 关键…

原生OpenFeign相较于传统HTTP工具的优化和原理

文章目录 1.HTTP工具使用流程及问题1.1 使用OkHttp3流程示例1.2 存在的两大问题 2.OpenFeign的优化3.OpenFeign实现原理3.1 使用Feign构造动态代理对象3.2 Feign动态代理的实现原理 本篇介绍的是springcloud-openfeign的底层框架io.github.openfeign&#xff0c;重点不是框架如…

【Redis】Redis缓存雪崩、缓存穿透、缓存击穿(热key问题)

目录 一、缓存穿透 1、概念 2、解决办法 1.缓存空对象 2.布隆过滤 二、缓存雪崩 1、概念 2、解决办法 1.给key设置随机的过期时间TTL 2.业务添加多级缓存 3.利用集群提供服务可用性 4.缓存业务添加降级限流 三、缓存击穿 1、概念 2、解决办法 1.互斥锁 2.逻辑…

数据结构:第三章 栈、队列和数组

文章目录 一、栈1.1栈的概念1.1.1栈的定义1.1.2栈的基本操作1.1.3栈的常见考题1.1.4小结 1.2栈的顺序存储实现1.2.1顺序栈的定义1.2.2初始化操作1.2.3进栈操作1.2.4出栈操作1.2.5获取栈顶元素操作1.2.6共享栈1.2.7小结 1.3栈的链式存储实现1.3.1链栈的定义1.3.2小结 二、队列2.…

Optional的使用详解

工作中经常会调外部接口、或者查询表等&#xff0c;如果对返回结果不进行空指针判断的话就会导致空指针异常。针对这种情况经常会使用if进行判断: private boolean isNotNull(Object param) {if (param null) {return false;} else {return true;}}这样写其实功能上没有任何问…

上班摸鱼在群里吹牛B,逮到一个阿里10年老测试开发,聊过之后收益良多...

老话说的好&#xff0c;这人呐&#xff0c;一单在某个领域鲜有敌手了&#xff0c;就会闲得蛋疼。前几天我在上班摸鱼刷群的时候认识了一位阿里测试开发大佬&#xff0c;在华为工作了10年&#xff0c;因为本人天赋比较高&#xff0c;平时工作也兢兢业业&#xff0c;现在企业内有…

USB协议分析仪

1 ULPI PHY passive sniffing mode 概念: non driving, no pull-up, no pull-down Function Control.opMode 1; // non-Driving OTG Control.DpPulldown 0; // no pull-down OTG Control.DmPulldown 0; // no pull-down USB IO.ChargerPullupEnDP 0; // no pull-up USB IO.…

九、MyBatis动态SQL

文章目录 九、动态SQL9.1 if9.2 where9.3 trim9.4 choose、when、otherwise9.5 foreach9.6 SQL片段 本人其他相关文章链接 九、动态SQL 9.1 if 总结&#xff1a;根据标签中test属性所对应的表达式决定标签中的内容是否需要拼接到SQL中。 User getUserByParamsWithIf(User user…

缓存击穿,穿透,雪崩

一、缓存穿透 是用户访问的数据既不在缓存当中&#xff0c;也不在数据库中。 如果从数据库查询不到数据&#xff0c;则不写入缓存。这就导致每次请求都会到数据库进行查询&#xff0c;缓存也失去了意义。 当高并发或有人利用不存在的Key频繁攻击时&#xff0c;数据库的压力骤…

AI 工具合辑盘点(四)持续更新

AI 视频生成和编辑工具 当今&#xff0c;视频已经成为最受欢迎的媒介之一。我们喜欢观看视频&#xff0c;但是制作高质量的视频需要耗费大量时间和精力。 无论你是内容创作者、专业视频编辑师&#xff0c;还是完全的新手&#xff0c;按照传统方式制作视频需要掌握各种知识、技…

【Maxwell】MySQL数据监听

背景 我们都知道随着业务的发展,监听数据库的数据变更及时性是必须的,虽然我们可以在入库之前进行处理,但是有个问题就是事务的一致性不好掌控,而且很多业务都是微服务的,那么不在一个微服务中,可能有需要跨服务去调用,那么此时直接去监听mysql的binlog来实现数据的操作…

这一篇Databinding应该可以帮助迅速上手吧

Databinding使用篇&#xff08;迅速上手&#xff09; 使用前需要在模块级别的build.gradle里面的android闭包里添加&#xff1a; dataBinding{enabled true}接着在layout文件中按下Alt 回车&#xff0c; 将布局转换成data binding layout即可&#xff0c;此时编译就会生成对…

【JAVAEE】创建线程的方式及线程的常用方法

目录 1.创建线程的四种方式 1.1继承Thread类 1.2实现Runnable接口 1.3匿名内部类 1.4lambda表达式 2.多线程的优势-增加运行速度 3.Thread类及常用方法 3.1构造方法 3.2常见属性 演示后台线程 演示线程是否存活 3.3线程中断 3.4线程等待-join() 3.5获取当前线程 …

23年5月高项备考学习笔记——信息系统管理

管理&#xff1a;监督系统的设计和结构 系统&#xff1a;提供蓝图 系统管理&#xff1a; 规划和组织&#xff1a;业务战略、组织机制、信息系统 业务战略&#xff1a; 总成本领先战略 差异性战略 专注化战略 设计和实施&#xff1a;战略转成需求&#xff0c;便管理&#xff1b…