本文中主要以《UI到底是怎么接受事件的事件》举例,讲述QT中关于时间机制的一些看法: 事件的产生过程: 1 首先由底层的硬件中断 à 操作系统(产生一个事件在其自己的事件队列中) 2 Qt中有一个 a.exec() 会帮我们建立一个事件循环 该循环一直在等在系统有事件传入 下列是一些示例代码: While(不为空队列) { If(是退出事件?) { 该APP退出; } If(分配事件到事件的函数;) {执行函数}; }
具体的说,a.exec() 会启动 event loop 实际上是启动的的是 QEventLoop 相关的函数: Qt's main event loop (QCoreApplication::exec()) fetches native window system events from the event queue, translates them into QEvents, and sends the translated events to QObjects.
Qt中的事件处理函数: 1 bool event(QEvent* ev); 该函数是Qt中所有事件进来后执行的第一个函数; 在源码中 该函数的实现过程大致为: bool event(QEvent* ev) { swtich(ev->type()) { Case QEvent::MouseButtonPress: mousePressEvent(ev);break; Case QEvent::KeyPress: keyPressEvent(ev);break; … } }
2 特定的事件处理函数: void mousePressEvent(QMouseEvent *event);//鼠标点击 void keyPressEvent(QKeyEvent *event);//键盘点击 void wheelEvent(QWheelEvent *event);//鼠标滚轮 (PS:我们如何查询 特定事件呢? 比如说我们现在是继承的QWidget 那么我们在man手册中查 QWidget,并在其中 搜索 event关键字) 3 事件过滤处理器 (意义:让事件发生后 在执行默认的事件处理函数的时候,也会执行我们所写的事件处理函数。我们把这个事件处理函数叫事件过滤处理器) 步骤: a 书写事件过滤处理器 bool eventFilter(QObject *obj, QEvent *event); //param1 obj :事件的执行者 param2:事件的类型 b 安装 à 谁想用我们事件过滤处理器,那么谁安装 (PS: 事件过滤处理器的返回值是bool通常情况下 有事件处理的话返回true没有的话 返回false。在最后 我们还是要调取一下父类的事件过滤器 return 父类::eventFilter(obj, event);) 4 事件过滤处理器的特殊使用 给QApplication安装事件过滤处理器(有什么好处呢?当事件传入到本APP的时候 ,不单单会执行传统的事件处理函数,还会执行我们的事件过滤处理器<全部的事件,全部的控件>) 5 notify()函数 (了解qApp->notify(ui->textEdit,keyevent);的用法) While(processEvent()) { If(是退出事件?) { 该APP退出; } If(notify()) {event()}; }
事件的发出: 事件的发出大概分两种情况: 1 硬件产生的(硬件在操作) 2 软件产生的(模拟硬件操作) 我们现在研究一下 如何软件产生事件: a. post方法 post方法会直接将事件发送到 event loop //异步的 QKeyEvent *keyevent = new QKeyEvent(QEvent::KeyPress, Qt::Key_A + i,Qt::NoModifier); //postEvent 发送事件 param1:发出者 param2:发出的事件 QCoreApplication::postEvent(this,keyevent);
b. send方法send方法会直接将事件发送的具体的个体 //同步的 QKeyEvent *keyevent = new QKeyEvent(QEvent::KeyPress, Qt::Key_A + i,Qt::NoModifier); //sendEvent 发送事件 param1:发送到谁 param2:发送的事件 //同步的 // QCoreApplication::sendEvent(ui->textEdit,keyevent); (PS:我们也可以使用qApp->notify(ui->textEdit,keyevent); 来达到 send的效果) (PS:对于事件的传递:
总体规则 :一个在某一个控件上发生的事件,那么它肯定会执行它的事件处理函数,如果该事件处理函数中对event进行了 accept 那么该事件不在向父控件传递;如果该事件处理函数中对event进行了 ignore 那么该事件继续向父控件传递; 默认情况下 ,我们是对event进行了 accept; 更多好内容可关注:华清远见 微信公众号,关注即送价值 399 的嵌入式相关电子书!
|