发表文章

[最新] Qt中连接到同一signal的多个slots的执行顺序问题(4.6以后按连接顺序执行)

lengyuezuixue 1月前 1

Manual

   Qt的问题,当manual中有明确文字说明时,我们应该以Qt的manual为准:

   If several slots are connected to one signal, the slots will be executed one after the other, in the order they have been connected, when the signal is emitted.

   恩,说的很明确,各个槽按照被connect的顺序被执行【注意,在队列模式时,是指相应的事件被post,仍不保证槽被按照该顺序执行】。

   翻翻Qt4.5以及该版本之前的manual,可以看到

   If several slots are connected to one signal, the slots will be executed one after the other, in an arbitrary order, when the signal is emitted.

源码

   恩,尝试看过元对象系统这部分源码的网友对这部分不会觉得陌生。如果没看过,可以瞅瞅这个Qt Meta Object system 学习(三)

  · QObject::connect() 最终将 信号和槽的索引值放置到一个Connection列表中

QObjectPrivate::Connection *c = new QObjectPrivate::Connection; 
    c->sender = s; 
    c->receiver = r; 
    c->method = method_index; 
    c->connectionType = type; 
    c->argumentTypes = types; 
    c->nextConnectionList = 0; 
QObjectPrivate::get(s)->addConnection(signal_index, c); 

   ·信号的发射,就是借助QMetaObject::activate() 来依次处理前面那个Connection列表总的项

do { 
        QObjectPrivate::Connection *c = connectionLists->at(signal_index).first; 
        if (!c) continue; 
        // We need to check against last here to ensure that signals added  
        // during the signal emission are not emitted in this emission. 
        QObjectPrivate::Connection *last = connectionLists->at(signal_index).last;
 
       do { 
            if (!c->receiver) 
                continue; 
             QObject * const receiver = c->receiver;

在该过程中:

   ·如果是直接连接,则通过 QMetaObject::metacall() 直接调用

  ·如果是队列连接,则post一个QMetaCallEvent事件,稍后通过事件派发,该事件的处理函数负责通过 QMetaObject::metacall() 调用相应的槽函数【注意,小心此时槽函数的执行顺序】

相关推荐
最新评论 (0)
返回
发表文章
lengyuezuixue
文章数
1098
评论数
1
注册排名
520350