⭐️我叫忆_恒心,一名喜欢书写博客的在读研究生👨🎓。
如果觉得本文能帮到您,麻烦点个赞
👍呗!
近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧,喜欢的小伙伴给个三连支持一下呗。👍⭐️❤️
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 坑点的地方要注意一下:
自定义按钮事件的时候,进行重写的时候,最好要调用父类的方法进行重写
。
问题 : 槽函数没有响应?
否则的话,要对一些信号的处理做一些额外工作,否则槽函数可能调用不了
// 以下是一个简单的示例程序,演示了如何解决槽函数没有相应的问题:
#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()
槽函数绑定。当鼠标点击按钮时,槽函数会被调用,并输出鼠标点击位置的坐标。
最后,最后
如果觉得有用,麻烦三连👍⭐️❤️支持一下呀,希望这篇文章可以帮到你,你的点赞是我持续更新的动力