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

news/2024/10/30 15:25:32/

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

近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧,喜欢的小伙伴给个三连支持一下呗。👍⭐️❤️
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_OBJECTpublic: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_OBJECTpublic: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.ppmy.cn/news/62102.html

相关文章

python 进程间通信 Queue()、Pipe()、manager.list()、manager.dict()、manager.Queue()

&#x1f468;‍&#x1f4bb;个人简介&#xff1a; 深度学习图像领域工作者 &#x1f389;总结链接&#xff1a; 链接中主要是个人工作的总结&#xff0c;每个链接都是一些常用demo&#xff0c;代码直接复制运行即可。包括&#xff1a; &am…

苹果备忘录误删了怎么恢复?恢复备忘录的3个方法!

案例&#xff1a;苹果删除的备忘录怎么恢复&#xff1f; 【友友们&#xff0c;苹果备忘录删除的备忘录在哪里可以恢复&#xff1f;有什么方法吗&#xff1f;】 苹果备忘录是日常生活中经常使用的一种记录方式&#xff0c;它可以帮助我们记录生活琐事、工作事项以及其他需要记录…

数据驱动的两阶段分布鲁棒(1-范数和∞-范数约束)的电热综合能源系统研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

docker php安装redis扩展

有这么一个情况&#xff0c;我在docker中&#xff0c;安装了镜像&#xff0c;也启动了容器&#xff0c;容器有&#xff1a;nginx、mysql、redis、php 是一个基本的开发环境 容器启动成功&#xff0c;我们先连接一下&#xff0c;看看是否正常。 先保证这些都ok&#xff0c;我们…

有三个线程T1,T2,T3,如何它们保证顺序执行?

目录 一、使用join方法 二、使用CountDownLatch&#xff08;闭锁&#xff09;&#xff1a; 三、使用单个线程池&#xff1a; 一、使用join方法 使用 join() 方法可以保证线程的顺序执行。在 Java 中&#xff0c;join() 方法是用来等待一个线程执行完成的方法&#xff0c;当调…

德国 DocuWare 文档管理软件平台

DocuWare 是一个先进的平台&#xff0c;可让您集中、快速、有效地管理、处理和利用业务信息。 我们的文档管理和工作流程解决方案的各项功能可以集成到任何 IT 系统中&#xff0c;可以数字化任何部门的手动或纸质业务流程。提高您公司的生产力&#xff0c;让您的团队更轻松地完…

《走进对象村4》之面向对象的第一大特性——封装

文章目录 &#x1f680;文章导读1、封装的概念2、访问限定修饰符3、如何进行封装4、封装的优点&#xff1a; &#x1f680;文章导读 在本篇文章中&#xff0c;将详细的对封装进行总结&#xff0c;文章仅仅是个人的一些理解&#xff0c;如果有错误的地方&#xff0c;还望指出看完…

易观千帆 | Q1运营报告:手机银行MAU超5.3亿,行业“内卷”超出想象

易观&#xff1a;由中国电子银行网、易观分析联合发布的“2023中国手机银行综合运营报告”显示&#xff1a;在经济企稳回升的大背景下&#xff0c;中国手机银行第一季度综合运营指数季度内呈平稳上升态势&#xff0c;手机银行活跃人数环比增幅逐月递增&#xff0c;促使活跃用户…