自主发送事件:
1、 阻塞型事件发送:
事件发送后需要等待事件处理完成
bool QCoreApplication::sendEvent ( QObject * receiver, QEvent * event ) [static]
2、非阻塞型事件发送:
事件发送后立即返回
事件被发送到事件队列中等待处理
voidQCoreApplication::postEvent ( QObject * receiver, QEvent * event ) [static]
注意事项:
1、 sendEvent()中的事件对象的生命周期由Qt程序管理,支持栈事件对象与堆事件对象的发送
2、postEvent()中的事件对象的生命周期由Qt平台管理,只能发送堆事件对象,事件被处理后由Qt平台销毁
//Widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QtGui/QWidget>
#include <QPushButton>
class Widget : public QWidget
{
Q_OBJECT
QPushButton m_pushButton;
void testSendEvent();
void testPostEvent();
protected slots:
void onButtonClicked();
public:
Widget(QWidget *parent = 0);
bool event(QEvent* evt);
~Widget();
};
#endif // WIDGET_H
//Widget.cpp
#include "Widget.h"
#include <QMouseEvent>
#include <QCoreApplication>
#include <QDebug>
Widget::Widget(QWidget *parent)
:QWidget(parent)
{
m_pushButton.setParent(this); //指定父子关系
m_pushButton.setText("Test");
connect(&m_pushButton, SIGNAL(clicked()), this,SLOT(onButtonClicked()));
}
//槽函数相当于是在事件处理函数内部调用的,槽函数执行完之前,事件处理函数未执行完毕,即当前事件对象正在被处理
void Widget::onButtonClicked()
{
// testSendEvent();
testPostEvent();
}
void Widget::testSendEvent()
{//定义事件对象,对象类型为鼠标双击事件,事件地点在0,0处,左键触发,后面两个参数指定鼠标与键盘的状态位
QMouseEvent dbcEvt(QEvent::MouseButtonDblClick, QPoint(0, 0),Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
qDebug() << "Before sendEvent()";
QCoreApplication::sendEvent(this,&dbcEvt); //为阻塞式的
//调用后的现象是为:下面的event()函数执行完毕后再打印的下面的"after sendevent",仿佛QCoreApplication::sendEvent函数直接调用了接收对象的event()函数
qDebug() << "After sendEvent()";
}
void Widget::testPostEvent()
{
QMouseEvent* dbcEvt = new QMouseEvent(QEvent::MouseButtonDblClick,QPoint(0, 0), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); //postEvent函数只能发送堆事件对象
qDebug() << "Before postEvent()";
QCoreApplication::postEvent(this,dbcEvt);//非阻塞式,调用后的现象是,打印完下面的"after postEvent"后才能看到event()函数被执行,事件被发送到了事件队列,需要根据事件队列中事件顺序依次处理事件
qDebug() << "After postEvent()";
}
bool Widget::event(QEvent* evt)
{
if( evt->type() == QEvent::MouseButtonDblClick )
{
qDebug() << "event(): " << evt;
}
return QWidget::event(evt);
}
Widget::~Widget()
{
}
自定义事件
意图自定义的事件类:
1、自定义的事件类必须继承自QEvent
2、自定义的事件类必须拥有全局唯一的Type值
3、程序中必须提供处理自定义事件对象的方法
步骤:
1、将QEvent作为父类继承
2、指定全局唯一的Type值
class XXXEvent : public QEvent //自定义的事件类必须继承自QEvent类
{
QString m_data;
public:
//自定义事件类必须拥有全局唯一的事件Type值,且需使用QEvent::User之后的值
const staticType TYPE = static_cast<Type>(QEvent::User + 0xFF);
//…..
};
3、处理自定义事件的常用方法
1)、给目标对象安装事件过滤器,在eventFilter()函数中编写自定义事件处理逻辑
2)、在目标对象类中重写event(),在event()函数中编写自定义事件的处理逻辑
事件的Type值:
1、每个Qt事件类都拥有全局唯一的Type值
2、自定义的事件类的Type值需要自定义
3、自定义事件类使用QEvent::User之后的值作为Type值,QEvent::User+ Value
4、需要保证应用程序中的自定义事件类的Type值:QEvent::User + Value全局唯一
//StringEvent.h
#ifndef _STRINGEVENT_H_
#define _STRINGEVENT_H_
#include <QEvent>
#include <QString>
class StringEvent : public QEvent //自定义的事件类必须继承自QEvent类
{
QString m_data;
public:
//自定义事件类必须拥有全局唯一的事件Type值,自定义事件需使用QEvent::User之后的值
const static Type TYPE = static_cast<Type>(QEvent::User + 0xFF);
explicit StringEvent(QString data = "");
QString data();
};
#endif // _STRINGEVENT_H_
// StringEvent.cpp
#include "StringEvent.h"
StringEvent::StringEvent(QString data) :QEvent(TYPE)
{
m_data = data;
}
QString StringEvent::data()
{
return m_data;
}
//Widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QtGui/QWidget>
#include <QLineEdit>
class Widget : public QWidget
{
Q_OBJECT
QLineEdit m_edit;
public:
Widget(QWidget *parent = 0);
bool event(QEvent* evt);
bool eventFilter(QObject* obj, QEvent* evt);
~Widget();
};
#endif // WIDGET_H
//Widget.cpp
#include "Widget.h"
#include "StringEvent.h"
#include <QMouseEvent>
#include <QDebug>
#include <QCoreApplication>
Widget::Widget(QWidget *parent)
:QWidget(parent), m_edit(this)
{
m_edit.installEventFilter(this);
}
//方法一: 重写目标对象的event()函数
bool Widget::event(QEvent* evt)
{
if( evt->type() == QMouseEvent::MouseButtonDblClick )
{
qDebug() << "event: Before sentEvent";
StringEvent e("Morning ");
QCoreApplication::sendEvent(&m_edit, &e); //发送事件对象
qDebug() << "event: After sentEvent";
}
return QWidget::event(evt);
}
//方法二:通过事件过滤器
bool Widget::eventFilter(QObject* obj,QEvent* evt)
{
if( (obj == &m_edit) && (evt->type() ==StringEvent::TYPE) )
{
StringEvent* se = dynamic_cast<StringEvent*>(evt);
qDebug() << "Receive: " << se->data();
m_edit.insert(se->data());
return true;
}
return QWidget::eventFilter(obj, evt);
}
Widget::~Widget()
{
}
声明:
此文根据 狄泰学院唐老师的《QT实验分析教程》创作