Qt 自定义事件

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 
#include 

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 

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

#endif // CUSTOMTHREAD_H
#include "customthread.h"
#include 
#include 
#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 
#include 

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()处理
}





你可能感兴趣的:(Qt)