如果使用ui acton编辑器,一般在代码中找不到生成的connnect函数,即关联信号与槽的函数,那么,信号与槽是怎么样关联起来的呢?是靠这个函数connectSlotsByName来实现的。至于更详细的原理性的细节,研究了一天只有一点点进展。我暂时不想探究了,以后有机会在研究。下面摘录了一篇文章,算是这个问题暂时够一段落。现象:在实验自动连接槽和信号的时候,发现如果不使用ui文件, 则似乎函数无效 而同样ui文件中也是使用 connectSlotsByName() 来完成关联的,单独提出来使用则似乎没有效果,感觉很是奇怪原因:connectSlotsByName 函数内查找object对象的children使用了objectname()函数 也就是这一句下文附的源码中这一句 QByteArray objName = co->objectName().toAscii();从 doc中看到 objectName : QString This property holds the name of this object. You can find an object by name (and type) using findChild(). You can find a set of objects with findChildren(). By default, this property contains an empty string.如果对象有children,那么这个children默认的 objectName属性缺省情况下是空串而在使用ui的时候connectSlotsByName有效,是因为ui文件保证了这些子体的objectName都非空 可以查看一下ui生成的.h文件, 发现所有的子对象,都使用了setObjectName() 而setObjectName(),显然就是给这些对象的objectName赋值。解决办法: 如果不使用ui文件, 那么仍想使用connectSlotsByName来自动关联signal 和 slot, 那么应该使用setObjectName()函数。附 connectSlotByName源码: void QMetaObject::connectSlotsByName(QObject *o) { if (!o) return; const QMetaObject *mo = o->metaObject(); Q_ASSERT(mo); const QObjectList list = qFindChildren<QObject *>(o, QString()); for (int i = 0; i < mo->methodCount(); ++i) { const char *slot = mo->method(i).signature(); Q_ASSERT(slot); if (slot[0] != "o" || slot[1] != "n" || slot[2] != "_") continue; bool foundIt = false; for(int j = 0; j < list.count(); ++j) { const QObject *co = list.at(j); QByteArray objName = co->objectName().toAscii(); int len = objName.length(); if (!len || qstrncmp(slot + 3, objName.data(), len) || slot[len+3] != "_") continue; int sigIndex = co->d_func()->signalIndex(slot + len + 4); if (sigIndex < 0) { // search for compatible signals const QMetaObject *smo = co->metaObject(); int slotlen = qstrlen(slot + len + 4) - 1; for (int k = 0; k < co->metaObject()->methodCount(); ++k) { QMetaMethod method = smo->method(k); if (method.methodType() != QMetaMethod::Signal) continue; if (!qstrncmp(method.signature(), slot + len + 4, slotlen)) { int signalOffset, methodOffset; computeOffsets(method.enclosingMetaObject(), &signalOffset, &methodOffset); sigIndex = k + - methodOffset + signalOffset; break; } } } if (sigIndex < 0) continue; if (QMetaObjectPrivate::connect(co, sigIndex, o, i)) { foundIt = true; break; } } if (foundIt) { // we found our slot, now skip all overloads while (mo->method(i + 1).attributes() & QMetaMethod::Cloned) ++i; } else if (!(mo->method(i).attributes() & QMetaMethod::Cloned)) { qWarning("QMetaObject::connectSlotsByName: No matching signal for %s", slot); } }