本文会讲到自定义事件、系统事件、postEvent和sendEvent。
实现自定义事件步骤:
1、定义自定义事件ID(范围0~65535),由于QT的系统事件ID都在0~1000,所有自定义事件ID要1001~65535以外(QEvent::User的值为1000)。
2、继承QEvent创建自定义事件类,注意初始化向量表时需要初始化事件ID。
3、以上两步准备好了,就可以发送和接收了,发送使用sendEvent或者postEvent,接收使用customEvent或者eventFilter来接收。
sendEvent或者postEvent的区别:
sendEvent:是同步执行,它一发送,就会通过notify直接执行相关事件,并且它是在栈区创建。
postEvent:是异步执行,它一发送,事件就会通过主线程的QEventLoop把它从输入事件队列queuedSocketEvents加到执行事件队列,然后按照顺序执行,并且它在堆区创建。
customEvent好像只能接收自定义事件,无法接收系统事件,所以要接收系统事件可以使用事件过滤器eventFilter来接收。
代码实例:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QEvent>
#include <QPushButton>
#include <QLabel>
#include <QGridLayout>
#include <QComboBox>
#include <QLineEdit>
#include <QTextEdit>
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
protected:
void customEvent(QEvent *event);
bool eventFilter(QObject *obj, QEvent *event);
private slots:
void slotsystem();
void slotusr();
private:
QLabel* m_systemlab;
QLabel* m_userlab;
QPushButton* m_systembtn;
QPushButton* m_userbtn;
QComboBox* m_systembox;
QLineEdit* m_useredit;
QTextEdit* m_textedit;
};
//定义自定义事件ID
const int userId = QEvent::User;
const int MyEventId = userId+6;
//继承QEvent创建自定义事件类,注意初始化向量表时需要初始化事件ID。
class MyEvent :public QEvent
{
public:
MyEvent(QObject*parent,QString val);
QString m_val;
QObject* m_parent;
};
#endif // WIDGET_H
#include "widget.h"
#include <QApplication>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent)
{
m_systemlab = new QLabel("系统事件:",this);
m_userlab = new QLabel("用户事件:",this);
m_systembox = new QComboBox(this);
m_useredit = new QLineEdit("0",this);
m_systembtn = new QPushButton("发送",this);
m_userbtn = new QPushButton("发送",this);
m_textedit = new QTextEdit(this);
m_systembox->addItems(QStringList()<<"Hide"<<"Show"<<"Close");
QGridLayout* lay = new QGridLayout(this);
lay->addWidget(m_systemlab,0,0,1,1);
lay->addWidget(m_systembox,0,1,1,1);
lay->addWidget(m_systembtn,0,2,1,1);
lay->addWidget(m_userlab,1,0,1,1);
lay->addWidget(m_useredit,1,1,1,1);
lay->addWidget(m_userbtn,1,2,1,1);
lay->addWidget(m_textedit,2,0,5,3);
this->setLayout(lay);
this->installEventFilter(this);
connect(m_systembtn,SIGNAL(clicked()),this,SLOT(slotsystem()));
connect(m_userbtn,SIGNAL(clicked()),this,SLOT(slotusr()));
}
Widget::~Widget()
{
}
//发送系统事件
void Widget::slotsystem()
{
#if 1
//1
if (m_systembox->currentText() == "Hide")
{
QEvent *e = new QEvent(QEvent::Hide);
QApplication::postEvent(this,e);
}
else if(m_systembox->currentText() == "Show")
{
QEvent *e = new QEvent(QEvent::Show);
QApplication::postEvent(this,e);
}
else if(m_systembox->currentText() == "Close")
{
QEvent *e = new QEvent(QEvent::Close);
QApplication::postEvent(this,e);
}
#else
//2
if (m_systembox->currentText() == "Hide")
{
QEvent e(QEvent::Hide);
QApplication::sendEvent(this,&e);
}
else if (m_systembox->currentText() == "Show")
{
QEvent e(QEvent::Show);
QApplication::sendEvent(this,&e);
}
else if (m_systembox->currentText() == "Close")
{
QEvent e(QEvent::Close);
QApplication::sendEvent(this,&e);
}
#endif
}
//发送自定义事件
void Widget::slotusr()
{
#if 0
//1
MyEvent* myevent = new MyEvent(this,m_useredit->text());
QApplication::postEvent(this,myevent);
#else
//2
MyEvent myevent(this,m_useredit->text());
QApplication::sendEvent(this,&myevent);
#endif
}
//只能接收自定义事件
void Widget::customEvent(QEvent *event)
{
if (event->type() == MyEventId)
{
MyEvent* e = dynamic_cast<MyEvent*>(event);
if (e)
{
m_textedit->append("customEvent接收事件:自定义事件:参数:"+e->m_val);
}
}
return QWidget::customEvent(event);
}
//接收自定义事件和系统事件
bool Widget::eventFilter(QObject* obj,QEvent* event)
{
if (event->type() == QEvent::Hide)
{
m_textedit->append("eventFilter接收事件:系统事件:参数:Hide");
}
else if (event->type() == QEvent::Show)
{
m_textedit->append("eventFilter接收事件:系统事件:参数:Show");
}
else if (event->type() == QEvent::Close)
{
m_textedit->append("eventFilter接收事件:系统事件:参数:Close");
}
if (event->type() == MyEventId)
{
MyEvent* e = dynamic_cast<MyEvent*>(event);
if (e)
{
m_textedit->append("eventFilter接收事件:自定义事件:参数:"+e->m_val);
}
}
}
//--------------------------MyEvent-----注意初始化向量表时需要初始化事件ID。
MyEvent::MyEvent(QObject *parent, QString val)
:QEvent(QEvent::Type(MyEventId)),m_parent(parent),m_val(val)
{
}