目录
发送事件:
发送事件(sendEvent)与发布事件(postEvent)
自定义事件
原理
创建自定义事件的方法和步骤
自定义事件的使用
static void QCoreApplication::postEvent (QObject* receiver, QEvent* event, int priority=Qt::NormalEventPriority); static bool QCoreApplication::sendEvent(QObject* receiver, QEvent* event)receiver :指向接收事件的对象 event :表示需要发送的事件 priority :表示事件的优先级,事件会按优先级排序,高优先级的事件排在队列的前 面。其取值为枚举类型 Qt::EventPriority 中的枚举值,如下 Qt::HighEventPriority:值为 1 。 Qt::NormalEventPriority:值为 0 。 Qt::LowEventPriority:值为 -1 。 优先级只是一个相对值,其值可取介于规定的最大值和最小值之间的任何值,比如可使 priority 参数的值为 Qt::HighEventPriority +10 。
1、发布 (post) 事件: ①、把事件添加到事件队列中,并立即返回。 ②、发布事件必须在堆 ( 比如使用 new) 上创建事件,因为事件被发布后,事件队列将 获得事件的所有权并自动将其删除。发布事件后再访问该事件是不安全的。 ③、发布事件还可以对事件进行合并 ( 或称为压缩 ) ,比如在返回事件循环之前连续发布了多个相同的事件,则这多个相同的事件会自动合并为一个单一的事件。可合并的事件有鼠标移动事件、调整大小事件等。 2、发送 (send) 事件: 把事件直接发送给接收事件的目标对象。事件发送之后不会被删除, 发送的事件通常创建在堆栈上。
①、基本原理: 事件其实就是使用的一个整数值表示的,因此在创建自定义事件时,只须给事件指定一个整数值即可,在 Qt 中,这个整数值是通过枚举类型 QEvent::Type 定义的,事件的其他信息可以封装在一个自定义的类之中。 ②、自定义的事件即可以是预定义类型,也可以是自定义类型的。 ③、自定义类型的事件,需要定义一个事件编号,该编号必须大于 QEvent :: User( 其值为 1000) ,小于 QEvent::MaxUser( 其值为 65535) 。 ④、各种事件不能重叠 ( 即 QEvent::Type 类型的值不能相同 ) ,小于 QEvent::User 的事件是 Qt 内部定义的事件,他们不会重叠,对于自定义的事件可以使用 registerEventType() 函数来保证事件不重叠,该函数原型: static int QEvent::registerEventType ( int hint = -1 ); 如果 hint 的值不会产生重叠,则会返回这个值;如果 hint 不合法,系统会自动分配一 个合法值并返回。因此,可使用该函数的返回值创建 Type 类型的值。
①、可以使用以下方式创建自定义事件 使用 QEvent 的构造函数创建事件,其原型为: QEvent(Type type); 示例: QEvent::Type t1=(QEvent::Type)1333; // 定义事件编号 QEvent e(t); // 创建事件 e 使用 Qt 已创建好的事件类型创建事件,比如使用 QKeyEvent 类创建键盘事件。 继承 QEvent 类,创建自定义事件 ②、使用 QCoreApplication::postEvent() 或 QCoreApplication::sendEvent() 函数发送事件。 ③、可使用以下方法处理自定义事件 重写 QObject::event() 函数,在该函数内直接处理自定义事件或调用自定义的事件处理函数处理事件。 安装事件过滤器,然后在过滤器对象的 eventFilter() 函数中处理自定义事件。 还可以重写 QCoreApplication::notify() 函数。
#include <QApplication> #include<QWidget> #include<QObject> #include <iostream> using namespace std; QEvent::Type t1=(QEvent::Type)1333; QEvent e(t1); //使用 QEvent 的构造函数在堆栈上创建自定义事件 class E:public QEvent { public: //子类化 QEvent 以创建自定义事件 //方式 1:使用静态成员。 //使用静态成员主要是为了正确初始化父类部分 QEvent,比如 //E():t2((QEvent::Type)1324),QEvent(t2){},若 t2 不是静态的,则则初始化之后 t2 为1324,但传递 //给 QEvent 的 t2 是一个不确定的值,因为按照 C++规则,对父类部分的初始化先于数据成员的初始化。 static QEvent::Type t2; //注意:不要使用名称t,因为QEvent类之中有一个名称为 t 的成员变量。 E():QEvent(t2) { } //方式 2:使用带一个参数的构造函数 QEvent::Type t3; explicit E(QEvent::Type t4):t3(t4),QEvent(t4){} }; QEvent::Type E::t2=(QEvent::Type)1334; class A:public QWidget { public: bool event(QEvent* e) { //重写 event 函数以处理自定义事件 if(e->type()==t1) //判断事件类型是否为 t1 { cout<<"AE"<<e->type()<<","; f1((E*)e); //调用自定义的处理函数处理该事件 return 1; } if(e->type()==E::t2) { cout<<"BE"<<e->type()<<","; f2((QEvent*)e); return 1; } if(e->type()==((E*)e)->t3) { cout<<"CE"<<e->type()<<","; f3((E*)e); return 1; } return QWidget::event(e); } //event 结束 //以下为处理自定义事件的事件处理函数 void f1(E *e) { cout<<"F1"<<endl; } void f2(QEvent *e) { cout<<"F2"<<endl; } void f3(E *e) { cout<<"F3"<<endl; } }; //类 A 结束。 int main(int argc, char *argv[]) { QApplication aa(argc,argv); A ma; E me; E *pe = new E((QEvent::Type)1335); //发布或发送事件 aa.sendEvent(&ma, &pe); aa.sendEvent(&ma, &me); aa.postEvent(&ma, &pe); //aa.postEvent(&ma, &me); //错误,发布的事件 me 必须是在堆上创建的。 ma.resize(333,222); ma.show(); aa.exec(); return 0; } 运行程序后,输出结果依次为 AE1333,F1 BE1334,F2 CE1335,F3