技术博客003
来源:互联网 发布:8管脚单片机 编辑:程序博客网 时间:2024/06/08 05:54
从Qobject(QObject.h)源码中可以看到QObject::connect的定义是这样的:[cpp] view plain copystatic 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 copyconnect(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 copyconnect(sender,SIGNAL(signal()),receiver,SLOT(slot())); 实际上就是connect(sender,“2signal()”,receiver,“1slot())”; 搞明白了实际的参数就可以来看connect的真正实现过程了,在QObject.cpp文件中可以找到connect的实现代码。[cpp] view plain copybool 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; }
阅读全文
0 0
- 技术博客003
- 技术博客
- 技术博客
- 技术博客
- 技术博客
- 技术博客
- 技术博客
- 技术博客
- 技术博客
- 技术博客
- 技术博客
- 技术博客
- 技术博客
- 技术博客
- 技术博客
- 技术博客
- 技术博客
- 技术博客
- HibernateTemplate和HibernateDaoSupport
- linux 多路转接之select
- Bottom Sheet的使用和BottomSheetDialogFragment的封装
- 详解java定时任务
- 关于open函数,一个很容易出错的问题
- 技术博客003
- 112. Path Sum
- 用rvest包爬取豆瓣图书数据
- Activity的launchMode介绍
- matlab 全局最优算法 GlobalSearch
- 郁闷!ionic中获取ng-model绑定的值为undefined如何解决
- java——与c++之不同——其他
- No mapping found for HTTP request with URI
- hdu5972 快速匹配bitset优化(shiftand算法)2016ACM/ICPC亚洲区大连站