技术博客003

从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;  
}  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 JavaScript 编写的记忆游戏(附源代码)   项目:JavaScript 记忆游戏(附源代码) 记忆检查游戏是一个使用 HTML5、CSS 和 JavaScript 开发的简单项目。这个游戏是关于测试你的短期 记忆技能。玩这个游戏 时,一系列图像会出现在一个盒子形状的区域中 。玩家必须找到两个相同的图像并单击它们以使它们消失。 如何运行游戏? 记忆游戏项目仅包含 HTML、CSS 和 JavaScript。谈到此游戏的功能,用户必须单击两个相同的图像才能使它们消失。 点击卡片或按下键盘键,通过 2 乘 2 旋转来重建鸟儿对,并发现隐藏在下面的图像! 如果翻开的牌面相同(一对),您就赢了,并且该对牌将从游戏中消失! 否则,卡片会自动翻面朝下,您需要重新尝试! 该游戏包含大量的 javascript 以确保游戏正常运行。 如何运行该项目? 要运行此游戏,您不需要任何类型的本地服务器,但需要浏览器。我们建议您使用现代浏览器,如 Google Chrome 和 Mozilla Firefox, 以获得更好、更优化的游戏体验。要玩游戏,首先,通过单击 memorygame-index.html 文件在浏览器中打开游戏。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值