Qt 自定义事件

本文介绍了Qt中自定义事件的使用,包括事件在多线程和单线程通讯中的作用,与信号槽机制的区别。自定义事件允许同步和异步分发,可以设置过滤器并携带自定义数据。创建自定义事件需要继承QEvent类,并通过QEvent::registerEventType()注册。发送事件可通过sendEvent()或postEvent(),前者同步,后者异步。重写event()或customEvent()函数接收处理事件。示例展示了如何在一个线程中使用自定义事件来显示时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Qt自定义事件

事件既可以用在多线程,也可以是单线程中对象间通讯

为什么使用事件?与信号槽的区别:

1.事件的分发既可以是同步的,又可以是异步的,槽的回调总是同步的

2.事件可以使用过滤器

3.事件可以携带自定义数据;信号槽传递数据,某些数据类型需要进行qRegisterMetaType注册

如何使用自定义事件

1.一个继承自QEvent的类

2.自定义事件的type来确定这个自定义事件

注意:需要和已经存在的type不能重复,系统保留了0-999的值,Qt定义了自定义事件的两个边界值:QEvent::User(1000)和

QEvent::MaxUser(65535)。Qt提供一个静态的自定义事件注册函数registerEventType()

3.自定义事件的发送

两种发送方式:sendEvent()和postEvent()两中函数,两者区别,sendEvent()是直接发送给接受者,发送之后,event对象并不会被销毁,通常是在栈上创建event对象;postEvent()是将事件加入到事件队列中,由事件循环处理,需要在堆上创建event对象,事件根据post顺序进行处理,可以指定高优先级进行优先处理,默认优先级为Qt::NormalEventPriority。sendPostedEvents()函数可以将参数中的类型事件立即发送给接受者进行处理,窗口系统的事件不由这个函数,而是postEvents()函数。

4.重写event()函数。这里也可以重写QObject::customEvent()函数。

下面是一个简单线程的自定义事件显示时间的例子

1.首先定义一个继承自QEvent的类

#ifndef CUSTOMEVENT_H
#define CUSTOMEVENT_H

#include <QEvent>
#include <QString>

class CustomEvent : public QEvent
{
public:
    CustomEvent(const QString &msg);
    static QEvent::Type rtEvType();
    static QEvent::Type m_eventType;
    QString m_msg;
};

#endif // CUSTOMEVENT_H

#include "customevent.h"

QEvent::Type CustomEvent::m_eventType = (QEvent::Type)QEvent::registerEventType();  //注册自定义事件的type

CustomEvent::CustomEvent(const QString &msg):
    QEvent(rtEvType()), m_msg(msg)
{
}

QEvent::Type CustomEvent::rtEvType()
{
    return m_eventType;
}


2.写一个简单的线程类来发送这个自定义事件

#ifndef CUSTOMTHREAD_H
#define CUSTOMTHREAD_H

#include <QThread>

class CustomThread : public QThread
{
    Q_OBJECT
public:
    explicit CustomThread(QObject *receiver);
    ~CustomThread();
    void run();
    QObject *m_receiver;
    
};

#endif // CUSTOMTHREAD_H
#include "customthread.h"
#include <QDateTime>
#include <QCoreApplication>
#include "customevent.h"

CustomThread::CustomThread(QObject *receiver) :
    m_receiver(receiver)
{
}

CustomThread::~CustomThread()
{
    wait();
}

void CustomThread::run()
{
    while(1) {
        QThread::msleep(1000);
        CustomEvent *ce = new CustomEvent(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));    //获取当前时间的自定义事件
        QCoreApplication::postEvent(m_receiver, ce); //发送事件
    }
}
3.在主线程中重写event处理自定义事件
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QLabel>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT
    
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    bool event(QEvent *e);
    
private:
    Ui::Widget *ui;
    QLabel *m_label;
};

#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
#include "customthread.h"
#include "customevent.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    m_label = new QLabel(this);

    CustomThread *thread = new CustomThread(this);
    thread->start();
}

Widget::~Widget()
{
    delete ui;
}

bool Widget::event(QEvent *e)
{
    if(e->type() == CustomEvent::rtEvType()) {
        CustomEvent *ce = (CustomEvent*)e;
        m_label->setText(ce->m_msg);
        m_label->adjustSize();
        e->accept();
        return true;
    }
    return QWidget::event(e);    //自定义事件以外的事件都由QWidget::event()处理
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值