从Qobject(QObject.h)源码中可以看到QObject::connect的定义是这样的: [cpp] view plain copy static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType = #ifdef qdoc Qt::AutoConnection #else #ifdef QT3_SUPPORT Qt::AutoCompatConnection #else Qt::AutoConnection #endif #endif ); inline bool connect(const QObject *sender, const char *signal, const char *member, Qt::ConnectionType type = #ifdef qdoc Qt::AutoConnection #else #ifdef QT3_SUPPORT Qt::AutoCompatConnection #else Qt::AutoConnection #endif #endif ) const; 其中第二个connect的实现其实只有一句话: [cpp] view plain copy { return connect(asender, asignal, this, amember, atype); } 所以对于connect函数的学习其实就是研究第一个connect函数。 我们在使用connect函数的时候一般是这样调用的: [cpp] view plain copy connect(sender,SIGNAL(signal()),receiver,SLOT(slot())); 这里用到了两个宏:SIGNAL() 和SLOT();通过connect声明可以知道这两个宏最后倒是得到一个const char*类型。 在qobjectdefs.h中可以看到SIGNAL() 和SLOT()的宏定义: [cpp] view plain copy #ifndef QT_NO_DEBUG # define QLOCATION "\0"__FILE__":"QTOSTRING(__LINE__) # define METHOD(a) qFlagLocation("0"#a QLOCATION) # define SLOT(a) qFlagLocation("1"#a QLOCATION) # define SIGNAL(a) qFlagLocation("2"#a QLOCATION) #else # define METHOD(a) "0"#a # define SLOT(a) "1"#a # define SIGNAL(a) "2"#a #endif 所以这两个宏的作用就是把函数名转换为字符串并且在前面加上标识符。 比如:SIGNAL(read())展开后就是"2read()";同理SLOT(read())展开后就是"1read()"。 [cpp] view plain copy connect(sender,SIGNAL(signal()),receiver,SLOT(slot())); 实际上就是connect(sender,“2signal()”,receiver,“1slot())”; 搞明白了实际的参数就可以来看connect的真正实现过程了,在QObject.cpp文件中可以找到connect的实现代码。 [cpp] view plain copy bool QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type) { { const void *cbdata[] = { sender, signal, receiver, method, &type }; if (QInternal::activateCallbacks(QInternal::ConnectCallback, (void **) cbdata)) return true; } if (sender == 0 || receiver == 0 || signal == 0 || method == 0) { qWarning("QObject::connect: Cannot connect %s::%s to %s::%s", sender ? sender->metaObject()->className() : "(null)", (signal && *signal) ? signal+1 : "(null)", receiver ? receiver->metaObject()->className() : "(null)", (method && *method) ? method+1 : "(null)"); return false; } QByteArray tmp_signal_name; if (!check_signal_macro(sender, signal, "connect", "bind")) return false; const QMetaObject *smeta = sender->metaObject(); const char *signal_arg = signal; ++signal; //skip code int signal_index = smeta->indexOfSignal(signal); if (signal_index < 0) { // check for normalized signatures tmp_signal_name = QMetaObject::normalizedSignature(signal - 1); signal = tmp_signal_name.constData() + 1; signal_index = smeta->indexOfSignal(signal); if (signal_index < 0) { err_method_notfound(sender, signal_arg, "connect"); err_info_about_objects("connect", sender, receiver); return false; } } QByteArray tmp_method_name; int membcode = extract_code(method); if (!check_method_code(membcode, receiver, method, "connect")) return false; const char *method_arg = method; ++method; // skip code const QMetaObject *rmeta = receiver->metaObject(); int method_index = -1; switch (membcode) { case QSLOT_CODE: method_index = rmeta->indexOfSlot(method); break; case QSIGNAL_CODE: method_index = rmeta->indexOfSignal(method); break; } if (method_index < 0) { // check for normalized methods tmp_method_name = QMetaObject::normalizedSignature(method); method = tmp_method_name.constData(); switch (membcode) { case QSLOT_CODE: method_index = rmeta->indexOfSlot(method); break; case QSIGNAL_CODE: method_index = rmeta->indexOfSignal(method); break; } } if (method_index < 0) { err_method_notfound(receiver, method_arg, "connect"); err_info_about_objects("connect", sender, receiver); return false; } if (!QMetaObject::checkConnectArgs(signal, method)) { qWarning("QObject::connect: Incompatible sender/receiver arguments" "\n %s::%s --> %s::%s", sender->metaObject()->className(), signal, receiver->metaObject()->className(), method); return false; } int *types = 0; if ((type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection) && !(types = queuedConnectionTypes(smeta->method(signal_index).parameterTypes()))) return false; QMetaObject::connect(sender, signal_index, receiver, method_index, type, types); const_cast<QObject*>(sender)->connectNotify(signal - 1); return true; }
技术博客003
猜你喜欢
转载自blog.csdn.net/sherryhaha123/article/details/72961685
今日推荐
周排行