深入探究connect函数

更新时间:2023-06-30 11:06:46 阅读: 评论:0

深⼊探究connect函数
connect,是QT中的连接函数,将信号发送者nder对象中的信号signal与接受者receiver中的member槽函数联系起来。
QObject::connect的定义是这样的:
static bool connect(const QObject *nder, const char *signal,
const QObject *receiver, const char *member, Qt::ConnectionType =
#ifdef qdoc
购买咖啡豆Qt::AutoConnection
#el
#ifdef QT3_SUPPORT
Qt::AutoCompatConnection
#el
Qt::AutoConnection
#endif
#endif
);
inline bool connect(const QObject *nder, const char *signal,
const char *member, Qt::ConnectionType type =
#ifdef qdoc
Qt::AutoConnection
#el
#ifdef QT3_SUPPORT
Qt::AutoCompatConnection
#el
Qt::AutoConnection
#endif
#endif
) const;
其中第⼆个connect的实现其实只有⼀句话:urgent怎么读
{ return connect(ander, asignal, this, amember, atype); }
所以对于connect函数的学习其实就是研究第⼀个connect函数。
在使⽤connect函数的时候⼀般是这样调⽤的:
connect(nder,SIGNAL(signal()),receiver,SLOT(slot()));
两个宏:SIGNAL() 和SLOT();通过connect声明可以知道这两个宏最后倒是得到⼀个const char*类型。
在qobjectdefs.h中可以看到SIGNAL() 和SLOT()的宏定义:
1. #ifndef QT_NO_DEBUG
2. # define QLOCATION "\0"__FILE__":"QTOSTRING(__LINE__)
3. # define METHOD(a)  qFlagLocation("0"#a QLOCATION)
4. # define SLOT(a)    qFlagLocation("1"#a QLOCATION)
5. # define SIGNAL(a)  qFlagLocation("2"#a QLOCATION)
6. #el
7. # define METHOD(a)  "0"#a
8. # define SLOT(a)    "1"#a
9. # define SIGNAL(a)  "2"#a
10. #endif
这两个宏的作⽤就是把函数名转换为字符串并且在前⾯加上标识符。
⽐如:SIGNAL(read())展开后就是"2read()";同理SLOT(read())展开后就是"1read()"。connect(nder,SIGNAL(signal()),receiver,SLOT(slot()));
实际上就是connect(nder,“2signal()”,receiver,“1slot())”;
在QObject.cpp⽂件中可以找到connect的实现代码,下⾯是去除了debug代码的connect实现。
1. bool QObject::connect(const QObject *nder, const char *signal,你来自哪里用英语怎么说
2.                      const QObject *receiver, const char *method,
3.                      Qt::ConnectionType type)
4. {
5.    {
6.        const void *cbdata[] = { nder, signal, receiver, method, &type };
7.        if (QInternal::activateCallbacks(QInternal::ConnectCallback, (void **) cbdata))
8.            return true;
9.    }
10.
11.    if (nder == 0 || receiver == 0 || signal == 0 || method == 0) {
12.        qWarning("QObject::connect: Cannot connect %s::%s to %s::%s",
13.                  nder ? nder->metaObject()->className() : "(null)",
14.                  (signal && *signal) ? signal+1 : "(null)",
15.                  receiver ? receiver->metaObject()->className() : "(null)",
16.                  (method && *method) ? method+1 : "(null)");
17.        return fal;
18.    }
19.    QByteArray tmp_signal_name;
20.
21.    if (!check_signal_macro(nder, signal, "connect", "bind"))
22.        return fal;
23.    const QMetaObject *smeta = nder->metaObject();托福学习
24.    const char *signal_arg = signal;
25.    ++signal; //skip code
26.    int signal_index = smeta->indexOfSignal(signal);
27.    if (signal_index < 0) {
28.        // check for normalized signatures
29.        tmp_signal_name = QMetaObject::normalizedSignature(signal - 1);
30.        signal = tmp_stData() + 1;
31.
32.        signal_index = smeta->indexOfSignal(signal);
33.        if (signal_index < 0) {
34.            err_method_notfound(nder, signal_arg, "connect");
35.            err_info_about_objects("connect", nder, receiver);
36.            return fal;
37.        }
38.    }
39.
40.    QByteArray tmp_method_name;
2014年巴西世界杯赛程41.    int membcode = extract_code(method);
42.
43.    if (!check_method_code(membcode, receiver, method, "connect"))
44.        return fal;
45.    const char *method_arg = method;
46.    ++method; // skip code
47.
48.    const QMetaObject *rmeta = receiver->metaObject();
49.    int method_index = -1;
50.    switch (membcode) {
51.    ca QSLOT_CODE:
52.        method_index = rmeta->indexOfSlot(method);
53.        break;
54.    ca QSIGNAL_CODE:
55.        method_index = rmeta->indexOfSignal(method);
56.        break;
57.    }
58.    if (method_index < 0) {
59.        // check for normalized methods
60.        tmp_method_name = QMetaObject::normalizedSignature(method);
61.        method = tmp_stData();
62.        switch (membcode) {
63.        ca QSLOT_CODE:
64.            method_index = rmeta->indexOfSlot(method);
64.            method_index = rmeta->indexOfSlot(method);
65.            break;
66.        ca QSIGNAL_CODE:
67.            method_index = rmeta->indexOfSignal(method);
68.            break;
69.        }
70.    }
71.
72.    if (method_index < 0) {
73.        err_method_notfound(receiver, method_arg, "connect");
74.        err_info_about_objects("connect", nder, receiver);
75.        return fal;
76.    }
77.    if (!QMetaObject::checkConnectArgs(signal, method)) {
78.        qWarning("QObject::connect: Incompatible nder/receiver arguments"
79.                  "\n        %s::%s --> %s::%s",
80.                  nder->metaObject()->className(), signal,
81.                  receiver->metaObject()->className(), method);
82.        return fal;
83.    }
84.
85.    int *types = 0;
86.    if ((type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection)
87.            && !(types = queuedConnectionTypes(smeta->method(signal_index).parameterTypes())))
88.        return fal;
89.
90.    QMetaObject::connect(nder, signal_index, receiver, method_index, type, types);
91.    const_cast<QObject*>(nder)->connectNotify(signal - 1);
92.    return true;
93. }
判断连接是否已经建⽴:
1. const void *cbdata[] = { nder, signal, receiver, method, &type };
cctv news在线直播2. if (QInternal::activateCallbacks(QInternal::ConnectCallback, (void **) cbdata))
3.      return true;
QInternal::ConnectCallback在qglobal.cpp中实现:
1. bool QInternal::activateCallbacks(Callback cb, void **parameters)
2. {
3.    Q_ASSERT_X(cb >= 0, "QInternal::activateCallback()", "Callback id must be a valid id");
4.
5.    QInternal_CallBackTable *cbt = global_callback_table();
6.    if (cbt && cb < cbt->callbacks.size()) {
7.        QList<qInternalCallback> callbacks = cbt->callbacks[cb];
bored怎么读
8.        bool ret = fal;
9.        for (int i=0; i<callbacks.size(); ++i)
10.            ret |= (callbacks.at(i))(parameters);
racer
11.        return ret;
12.    }
13.    return fal;
14. }
QInternal_CallBackTable 定义为(qglobal.cpp):
1. struct QInternal_CallBackTable {
shapeofmyheart2.    QVector<QList<qInternalCallback> > callbacks;
3. };
qInternalCallback定义为(qnamespace.h):
1. typedef bool (*qInternalCallback)(void **);
//这是⼀个函数指针 返回值是bool,只有⼀个参数为void**。这个指针在调⽤registerCallback加⼊列表。
typedef bool (*qInternalCallback)(void **);这是⼀个函数指针返回值是bool,只有⼀个参数为void**。这个指针在调⽤registerCallback加⼊列表。
判断signal是否合法
1. if (!check_signal_macro(nder, signal, "connect", "bind"))
2.    return fal;hoho
在QObject.cpp⽂件中可以找到check_signal_macro的实现

本文发布于:2023-06-30 11:06:46,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/78/1070074.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:函数   信号   连接   是否   判断   实现
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图