QT sendEvent()和postEvent()
来源:互联网 发布:软件项目验收单 编辑:程序博客网 时间:2024/06/04 20:05
QT文档中这样解释:
sendEvent(QObject* receiver,QEvent* event)
使用notify()函数直接给receiver发送事件。
postEvent(QObject* receiver, QEvent* event)
向事件队列中添加receiver和event。
简单说,sendEvent使用的是同步处理事件,postEvent使用的异步处理事件
sendEvent代码分析
-
inline bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event) -
{ if (event) event->spont = false; return self ? self->notifyInternal(receiver, event) : false; }
直接调用notifyInternal接口,注意中间设置自发消息标志位为false,同时还需要判断self是有有效(QCoreApplication是否启动)
-
bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event) -
{ -
// Make it possible for Qt Jambi and QSA to hook into events even -
// though QApplication is subclassed… -
bool result = false; -
void *cbdata[] = { receiver, event, &result }; -
if (QInternal::activateCallbacks(QInternal::EventNotifyCallback, cbdata)) { -
return result; -
} -
-
// Qt enforces the rule that events can only be sent to objects in -
// the current thread, so receiver->d_func()->threadData is -
// equivalent to QThreadData::current(), just without the function -
// call overhead. -
QObjectPrivate *d = receiver->d_func(); -
QThreadData *threadData = d->threadData; -
++threadData->loopLevel; -
-
bool returnValue = notify(receiver, event); -
–threadData->loopLevel; -
return returnValue; -
}
删除了一些不重要的代码,notifyInternal的主要作用是activateCallbacks,直接看notify
-
bool QCoreApplication::notify(QObject *receiver, QEvent *event) -
{ -
Q_D(QCoreApplication); -
// no events are delivered after ~QCoreApplication() has started -
if (QCoreApplicationPrivate::is_app_closing) -
return true; -
if (receiver == 0) { // serious error -
qWarning(”QCoreApplication::notify: Unexpected null receiver”); -
return true; -
} -
return receiver->isWidgetType() ? false : d->notify_helper(receiver, event); -
}
这个接口在QT文档上有注释。注意其中当receiver为控件时,不进行处理。
-
bool QCoreApplicationPrivate::notify_helper(QObject receiver, QEvent event) -
{ -
// send to all application event filters -
if (sendThroughApplicationEventFilters(receiver, event)) -
return true; -
// send to all receiver event filters -
if (sendThroughObjectEventFilters(receiver, event)) -
return true; -
// deliver the event -
return receiver->event(event); -
}
在这里可以看到事件是如何处理的:
- 先送入Application的事件过滤器,看看是否在事件过滤器中处理
- 再查看receiver是否有此事件的过滤器
- 最后,将事件送入receiver的event接口。
从整个过程来看,可以认为sendEvent直接调用了receiver的event接口。因此,可以认为处理方式为同步处理方式。
PostEvent分析
-
void QCoreApplication::postEvent(QObject *receiver, QEvent *event) -
{ -
postEvent(receiver, event, Qt::NormalEventPriority); -
}
-
void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority) -
{ -
… -
QThreadData volatile pdata = &receiver->d_func()->threadData; //得到线程信息 -
QThreadData *data = *pdata; -
if (!data) { -
// posting during destruction? just delete the event to prevent a leak -
delete event; -
return; -
} -
-
// lock the post event mutex -
data->postEventList.mutex.lock(); -
-
// if object has moved to another thread, follow it -
while (data != *pdata) { <span style=“font-family: Arial, Helvetica, sans-serif;”>//在这里判断receiver线程信息是否发生变化。(有可能是另外一个线程调用用receiver->moveToThread)</span> -
data->postEventList.mutex.unlock(); -
-
data = *pdata; -
if (!data) { -
// posting during destruction? just delete the event to prevent a leak -
delete event; -
return; -
} -
-
data->postEventList.mutex.lock(); -
} -
//这里postEventList还是被锁着的。 -
// if this is one of the compressible events, do compression -
if (receiver->d_func()->postedEvents -
&& self && self->compressEvent(event, receiver, &data->postEventList)) { -
data->postEventList.mutex.unlock();//这个事件有可能被压缩(实际上是发现队列中有这个事件还没有被处理,且这个事件是可以被压缩的,例如paintevent) -
return; -
} -
-
event->posted = true; -
++receiver->d_func()->postedEvents; -
if (event->type() == QEvent::DeferredDelete && data == QThreadData::current()) { -
// remember the current running eventloop for DeferredDelete -
// events posted in the receiver’s thread -
event->d = reinterpret_cast<QEventPrivate *>(quintptr(data->loopLevel)); //receiver即将被析构? -
} -
//将事件添加到postEventList中,注意这里的优先级第一个最高,最后一个优先级最低 -
if (data->postEventList.isEmpty() || data->postEventList.last().priority >= priority) { -
// optimization: we can simply append if the last event in -
// the queue has higher or equal priority -
data->postEventList.append(QPostEvent(receiver, event, priority)); -
} else { -
// insert event in descending priority order, using upper -
// bound for a given priority (to ensure proper ordering -
// of events with the same priority) -
QPostEventList::iterator begin = data->postEventList.begin() -
+ data->postEventList.insertionOffset, -
end = data->postEventList.end(); -
QPostEventList::iterator at = qUpperBound(begin, end, priority); -
data->postEventList.insert(at, QPostEvent(receiver, event, priority)); -
} -
data->canWait = false; -
data->postEventList.mutex.unlock();//在这里解除锁 -
//receiver所在的线程调用eventDispatcher处理postEventList -
if (data->eventDispatcher) -
data->eventDispatcher->wakeUp(); -
}
从上面可以看出,postEvent实际上是将事件添加到receiver所在线程中的一个队列中,至于这个队列所在的线程什么时候处理这个事件,postEvent是无法控制的
</div>
阅读全文
0 0
- QT sendEvent()和postEvent()
- QT sendEvent()和postEvent()
- QT 之 sendEvent & PostEvent
- CTK 事件管理机制(sendEvent()/postEvent())
- QEvent postEvent/sendEvent
- QEvent postEvent/sendEvent
- QEvent postEvent/sendEvent
- QEvent postEvent/sendEvent
- Qt postEvent
- [Qt] postevent emit
- qt2.2 多线程发送消息 QThread::postEvent postEvent qApp->postEvent QApplication qt 消息
- [Qt] postevent emit ----event与signal
- qt信号与槽代替postevent
- android getevnet 和 sendevent
- sendevent
- sendevent
- 【android学习】getevent和sendevent
- getevent和sendevent大总结
- UVA11627 Slalom 障碍滑雪
- TweakBit PCRepairKit(系统修复工具)官方正式版V1.8.3.6下载 | PCRepairKit破解版
- spring 5.0 IOC底层讲解 05
- SI24R1无线2.4G收发模块
- 64位windowes系统实现 gpt和mbr 双引导
- QT sendEvent()和postEvent()
- 70. Climbing Stairs
- webService一种简单的使用
- 我的lua 学习2
- java代码优化的小建议
- 越越的交通指挥系统 (traffic.pas/c/cpp)
- 彻底理解js中this的指向,不必硬背。
- CTS测试框架 -- RegexTrie
- 最简单的目标跟踪--模版匹配opencv