生活随笔
收集整理的這篇文章主要介紹了
6. Qt 信号与信号槽 (6)- QObject::connect
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
函數調用流程為:
QObject::connect ->QObject::connectImpl
->
QObjectPrivate::connectImpl
->
QObjectPrivate::get(s)->addConnection
class QObject{
static inline QMetaObject
::Connection
connect(const typename QtPrivate
::FunctionPointer
<Func1
>::Object
*sender
, Func1 signal
, const typename QtPrivate
::FunctionPointer
<Func2
>::Object
*receiver
, Func2 slot
,Qt
::ConnectionType type
= Qt
::AutoConnection
){...return connectImpl(sender
, reinterpret_cast<void **>(&signal
),receiver
, reinterpret_cast<void **>(&slot
),new QtPrivate
::QSlotObject
<Func2
, typename QtPrivate
::List_Left
<typename SignalType
::Arguments
, SlotType
::ArgumentCount
>::Value
,typename SignalType
::ReturnType
>(slot
),type
, types
, &SignalType
::Object
::staticMetaObject
);
...
}QMetaObject
::Connection QObject
::connectImpl(const QObject
*sender
, void **signal
,const QObject
*receiver
, void **slot
,QtPrivate
::QSlotObjectBase
*slotObj
, Qt
::ConnectionType type
,const int *types
, const QMetaObject
*senderMetaObject
)
{if (!signal
) {qWarning("QObject::connect: invalid null parameter");if (slotObj
)slotObj
->destroyIfLastRef();return QMetaObject
::Connection();}int signal_index
= -1;void *args
[] = { &signal_index
, signal
};for (; senderMetaObject
&& signal_index
< 0; senderMetaObject
= senderMetaObject
->superClass()) {senderMetaObject
->static_metacall(QMetaObject
::IndexOfMethod
, 0, args
);if (signal_index
>= 0 && signal_index
< QMetaObjectPrivate
::get(senderMetaObject
)->signalCount
)break;}if (!senderMetaObject
) {qWarning("QObject::connect: signal not found in %s", sender
->metaObject()->className());slotObj
->destroyIfLastRef();return QMetaObject
::Connection(0);}signal_index
+= QMetaObjectPrivate
::signalOffset(senderMetaObject
);return QObjectPrivate
::connectImpl(sender
, signal_index
, receiver
, slot
, slotObj
, type
, types
, senderMetaObject
);
}QMetaObject
::Connection QObjectPrivate
::connectImpl(const QObject
*sender
, int signal_index
,const QObject
*receiver
, void **slot
,QtPrivate
::QSlotObjectBase
*slotObj
, Qt
::ConnectionType type
,const int *types
, const QMetaObject
*senderMetaObject
)
{if (!sender
|| !receiver
|| !slotObj
|| !senderMetaObject
) {const char *senderString
= sender
? sender
->metaObject()->className(): senderMetaObject
? senderMetaObject
->className(): "Unknown";const char *receiverString
= receiver
? receiver
->metaObject()->className(): "Unknown";qWarning("QObject::connect(%s, %s): invalid null parameter", senderString
, receiverString
);if (slotObj
)slotObj
->destroyIfLastRef();return QMetaObject
::Connection();}QObject
*s
= const_cast<QObject
*>(sender
);QObject
*r
= const_cast<QObject
*>(receiver
);QOrderedMutexLocker
locker(signalSlotLock(sender
),signalSlotLock(receiver
));if (type
& Qt
::UniqueConnection
&& slot
) {QObjectConnectionListVector
*connectionLists
= QObjectPrivate
::get(s
)->connectionLists
;if (connectionLists
&& connectionLists
->count() > signal_index
) {const QObjectPrivate
::Connection
*c2
=(*connectionLists
)[signal_index
].first
;while (c2
) {if (c2
->receiver
== receiver
&& c2
->isSlotObject
&& c2
->slotObj
->compare(slot
)) {slotObj
->destroyIfLastRef();return QMetaObject
::Connection();}c2
= c2
->nextConnectionList
;}}type
= static_cast<Qt
::ConnectionType
>(type
^ Qt
::UniqueConnection
);}QScopedPointer
<QObjectPrivate
::Connection
> c(new QObjectPrivate
::Connection
);c
->sender
= s
;c
->signal_index
= signal_index
;c
->receiver
= r
;c
->slotObj
= slotObj
;c
->connectionType
= type
;c
->isSlotObject
= true;if (types
) {c
->argumentTypes
.store(types
);c
->ownArgumentTypes
= false;}QObjectPrivate
::get(s
)->addConnection(signal_index
, c
.data());QMetaObject
::Connection
ret(c
.take());locker
.unlock();QMetaMethod method
= QMetaObjectPrivate
::signal(senderMetaObject
, signal_index
);Q_ASSERT(method
.isValid());s
->connectNotify(method
);return ret
;
}QMetaObject
::Connection QMetaObject
::connect(const QObject
*sender
, int signal_index
,const QObject
*receiver
, int method_index
, int type
, int *types
)
{const QMetaObject
*smeta
= sender
->metaObject();signal_index
= methodIndexToSignalIndex(&smeta
, signal_index
);return Connection(QMetaObjectPrivate
::connect(sender
, signal_index
, smeta
,receiver
, method_index
,0, type
, types
));
}
QObjectPrivate
::Connection
*QMetaObjectPrivate
::connect(const QObject
*sender
,int signal_index
, const QMetaObject
*smeta
,const QObject
*receiver
, int method_index
,const QMetaObject
*rmeta
, int type
, int *types
)
{QObject
*s
= const_cast<QObject
*>(sender
);QObject
*r
= const_cast<QObject
*>(receiver
);int method_offset
= rmeta
? rmeta
->methodOffset() : 0;Q_ASSERT(!rmeta
|| QMetaObjectPrivate
::get(rmeta
)->revision
>= 6);QObjectPrivate
::StaticMetaCallFunction callFunction
=rmeta
? rmeta
->d
.static_metacall
: 0;QOrderedMutexLocker
locker(signalSlotLock(sender
),signalSlotLock(receiver
));if (type
& Qt
::UniqueConnection
) {QObjectConnectionListVector
*connectionLists
= QObjectPrivate
::get(s
)->connectionLists
;if (connectionLists
&& connectionLists
->count() > signal_index
) {const QObjectPrivate
::Connection
*c2
=(*connectionLists
)[signal_index
].first
;int method_index_absolute
= method_index
+ method_offset
;while (c2
) {if (!c2
->isSlotObject
&& c2
->receiver
== receiver
&& c2
->method() == method_index_absolute
)return 0;c2
= c2
->nextConnectionList
;}}type
&= Qt
::UniqueConnection
- 1;}QScopedPointer
<QObjectPrivate
::Connection
> c(new QObjectPrivate
::Connection
);c
->sender
= s
;c
->signal_index
= signal_index
;c
->receiver
= r
;c
->method_relative
= method_index
;c
->method_offset
= method_offset
;c
->connectionType
= type
;c
->isSlotObject
= false;c
->argumentTypes
.store(types
);c
->nextConnectionList
= 0;c
->callFunction
= callFunction
;QObjectPrivate
::get(s
)->addConnection(signal_index
, c
.data());locker
.unlock();QMetaMethod smethod
= QMetaObjectPrivate
::signal(smeta
, signal_index
);if (smethod
.isValid())s
->connectNotify(smethod
);return c
.take();
}
總結
以上是生活随笔為你收集整理的6. Qt 信号与信号槽 (6)- QObject::connect的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。