11.QT事件机制源码时序分析(下)

本文深入解析了Qt事件机制的核心流程,包括QCoreApplication::sendEvent和QCoreApplication::sendPostedEvents的具体实现,以及事件过滤器的工作原理。

接上一篇文章https://blog.youkuaiyun.com/Master_Cui/article/details/109182406,本文继续解析QCoreApplication::sendEvent和QCoreApplication::sendPostedEvents的代码

先看下QCoreApplication::sendEvent

bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
{
    Q_TRACE(QCoreApplication_sendEvent, receiver, event, event->type());

    if (event)
        event->spont = false;
    return notifyInternal2(receiver, event);
}//sendEvent直接调用了notifyInternal2

bool QCoreApplication::notifyInternal2(QObject *receiver, QEvent *event)
{
    bool selfRequired = QCoreApplicationPrivate::threadRequiresCoreApplication();
    if (!self && selfRequired)
        return false;

    // Make it possible for Qt Script to hook into events even
    // though QApplication is subclassed...
    bool result = false;
    void *cbdata[] = { receiver, event, &result };
    if (QInternal::activateCallbacks(QInternal::EventNotifyCallback, cbdata)) {//将事件通知的回调函数放到一个qlist中,永远返回false
        return result;
    }

    // Qt强制执行以下规则:事件只能发送到当前线程中的对象
    //所以receiver->d_func()->threadData和等效QThreadData::current()
    // 只是为了减少函数调用的开销
    QObjectPrivate *d = receiver->d_func();
    QThreadData *threadData = d->threadData;
    QScopedScopeLevelCounter scopeLevelCounter(threadData);
    if (!selfRequired)
        return doNotify(receiver, event);//分别调用doNotify和notify
    return self->notify(receiver, event);
}

bool QCoreApplication::notify(QObject *receiver, QEvent *event)
{
    if (QCoreApplicationPrivate::is_app_closing)// no events are delivered after ~QCoreApplication() has started
        return true;
    return doNotify(receiver, event);
}//即使调用notify,最终还是要调用doNotify

上述代码的时序就是sendEvent-》notifyInternal2-》notify-》doNotify

 

接着看下doNotify的实现

static bool doNotify(QObject *receiver, QEvent *event)
{
    if (receiver == 0) {                        // serious error
        qWarning("QCoreApplication::notify: Unexpected null receiver");
        return true;
    }

#ifndef QT_NO_DEBUG
    QCoreApplicationPrivate::checkReceiverThread(receiver);//检查接收者的线程是否和当前线程一致
#endif

    return receiver->isWidgetType() ? false : QCoreApplicationPrivate::notify_helper(receiver, event);//接收者是否是窗口,如果是,返回false,不处理,否则调用notify_helper
}

bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
{
    // Note: when adjusting the tracepoints in here
    // consider adjusting QApplicationPrivate::notify_helper too.
    Q_TRACE(QCoreApplication_notify_entry, receiver, event, event->type());
    bool consumed = false;
    bool filtered = false;
    Q_TRACE_EXIT(QCoreApplication_notify_exit, consumed, filtered);

    // 发送事件到所有应用程序的事件过滤器(仅在主线程中执行任何操作)
    if (QCoreApplication::self
            && receiver->d_func()->threadData->thread.loadAcquire() == mainThread()
            && QCoreApplication:
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值