QT connect函数的用法.docx
- 文档编号:6208535
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:14
- 大小:25.37KB
QT connect函数的用法.docx
《QT connect函数的用法.docx》由会员分享,可在线阅读,更多相关《QT connect函数的用法.docx(14页珍藏版)》请在冰豆网上搜索。
QTconnect函数的用法
QTQObject:
:
connect函数的学习
从Qobject(QObject.h)源码中可以看到QObject:
:
connect的定义是这样的:
[cpp] viewplaincopy
1.static bool connect(const QObject *sender, const char *signal,
2. const QObject *receiver, const char *member, Qt:
:
ConnectionType =
3. #ifdef qdoc
4. Qt:
:
AutoConnection
5. #else
6. #ifdef QT3_SUPPORT
7. Qt:
:
AutoCompatConnection
8. #else
9. Qt:
:
AutoConnection
10. #endif
11. #endif
12. );
13.inline bool connect(const QObject *sender, const char *signal,
14. const char *member, Qt:
:
ConnectionType type =
15. #ifdef qdoc
16. Qt:
:
AutoConnection
17. #else
18. #ifdef QT3_SUPPORT
19. Qt:
:
AutoCompatConnection
20. #else
21. Qt:
:
AutoConnection
22. #endif
23. #endif
24. ) const;
其中第二个connect的实现其实只有一句话:
[cpp] viewplaincopy
1.{ return connect(asender, asignal, this, amember, atype); }
所以对于connect函数的学习其实就是研究第一个connect函数。
我们在使用connect函数的时候一般是这样调用的:
[cpp] viewplaincopy
1.connect(sender,SIGNAL(signal()),receiver,SLOT(slot()));
这里用到了两个宏:
SIGNAL()和SLOT();通过connect声明可以知道这两个宏最后倒是得到一个constchar*类型。
在qobjectdefs.h中可以看到SIGNAL()和SLOT()的宏定义:
[cpp] viewplaincopy
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.#else
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()"。
[cpp] viewplaincopy
1.connect(sender,SIGNAL(signal()),receiver,SLOT(slot()));
2.实际上就是connect(sender,“2signal()”,receiver,“1slot())”;
搞明白了实际的参数就可以来看connect的真正实现过程了,在QObject.cpp文件中可以找到connect的实现代码。
[cpp] viewplaincopy
1.bool QObject:
:
connect(const QObject *sender, const char *signal,
2. const QObject *receiver, const char *method,
3. Qt:
:
ConnectionType type)
4.{
5. {
6. const void *cbdata[] = { sender, signal, receiver, method, &type };
7. if (QInternal:
:
activateCallbacks(QInternal:
:
ConnectCallback, (void **) cbdata))
8. return true;
9. }
10.
11. if (sender == 0 || receiver == 0 || signal == 0 || method == 0) {
12. qWarning("QObject:
:
connect:
Cannot connect %s:
:
%s to %s:
:
%s",
13. sender ?
sender->metaObject()->className() :
"(null)",
14. (signal && *signal) ?
signal+1 :
"(null)",
15. receiver ?
receiver->metaObject()->className() :
"(null)",
16. (method && *method) ?
method+1 :
"(null)");
17. return false;
18. }
19. QByteArray tmp_signal_name;
20.
21. if (!
check_signal_macro(sender, signal, "connect", "bind"))
22. return false;
23. const QMetaObject *smeta = sender->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_signal_name.constData() + 1;
31.
32. signal_index = smeta->indexOfSignal(signal);
33. if (signal_index < 0) {
34. err_method_notfound(sender, signal_arg, "connect");
35. err_info_about_objects("connect", sender, receiver);
36. return false;
37. }
38. }
39.
40. QByteArray tmp_method_name;
41. int membcode = extract_code(method);
42.
43. if (!
check_method_code(membcode, receiver, method, "connect"))
44. return false;
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. case QSLOT_CODE:
52. method_index = rmeta->indexOfSlot(method);
53. break;
54. case 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_method_name.constData();
62. switch (membcode) {
63. case QSLOT_CODE:
64. method_index = rmeta->indexOfSlot(method);
65. break;
66. case 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", sender, receiver);
75. return false;
76. }
77. if (!
QMetaObject:
:
checkConnectArgs(signal, method)) {
78. qWarning("QObject:
:
connect:
Incompatible sender/receiver arguments"
79. "\n %s:
:
%s --> %s:
:
%s",
80. sender->metaObject()->className(), signal,
81. receiver->metaObject()->className(), method);
82. return false;
83. }
84.
85. int *types = 0;
86. if ((type == Qt:
:
QueuedConnection || type == Qt:
:
BlockingQueuedConnection)
87. && !
(types = queuedConnectionTypes(smeta->method(signal_index).parameterTypes())))
88. return false;
89.
90. QMetaObject:
:
connect(sender, signal_index, receiver, method_index, type, types);
91. const_cast
92. return true;
93.}
上面是去除了debug代码的connect实现。
[cpp] viewplaincopy
1.const void *cbdata[] = { sender, signal, receiver, method, &type };
2.if (QInternal:
:
activateCallbacks(QInternal:
:
ConnectCallback, (void **) cbdata))
3. return true;
判断连接是否已经建立。
QInternal:
:
ConnectCallback在qglobal.cpp中实现。
[cpp] viewplaincopy
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
8. bool ret = false;
9. for (int i=0; i 10. ret |= (callbacks.at(i))(parameters); 11. return ret; 12. } 13. return false; 14.} QInternal_CallBackTable定义为(qglobal.cpp) [cpp] viewplaincopy 1.struct QInternal_CallBackTable { 2. QVector 3.}; qInternalCallback定义为(qnamespace.h) [cpp] viewplaincopy 1.typedef bool (*qInternalCallback)(void **);这是一个函数指针 返回值是bool,只有一个参数为void**。 这个指针在调用registerCallback加入列表。 [cpp] viewplaincopy 1.if (! check_signal_macro(sender, signal, "connect", "bind")) 2. return false; 判断signal是否合法。 在QObject.cpp文件中可以找到check_signal_macro的实现 [cpp] viewplaincopy 1.static bool check_signal_macro(const QObject *sender, const char *signal, 2. const char *func, const char *op) 3.{ 4. int sigcode = extract_code(signal); 5. if (sigcode ! = QSIGNAL_CODE) { 6. if (sigcode == QSLOT_CODE) 7. qWarning("Object: : %s: Attempt to %s non-signal %s: : %s", 8. func, op, sender->metaObject()->className(), signal+1); 9. else 10. qWarning("Object: : %s: Use the SIGNAL macro to %s %s: : %s", 11. func, op, sender->metaObject()->className(), signal); 12. return false; 13. } 14. return true; 15.} extract的实现也在QObject中,它就是去字符串第一个字符,并且只取低2位的值。 [cpp] viewplaincopy 1.static int extract_code(const char *member) 2.{ 3. // extract code, ensure QMETHOD_CODE <= code <= QSIGNAL_CODE 4. return (((int)(*member) - '0') & 0x3); 5.} 这里又有两个宏: QSIGNAL_CODE和QSLOT_CODE。 它们也是在qobjectdefs.h文件中定义的。 [cpp] viewplaincopy 1.#ifdef QT3_SUPPORT 2.#define METHOD_CODE 0 // member type codes 3.#define SLOT_CODE 1 4.#define SIGNAL_CODE 2 5.#endif 这个定义与之前的SIGNAL和SLOT的定义是对应的。 [cpp] viewplaincopy 1.const QMetaObject *smeta = sender->metaObject(); 2.const char *signal_arg = signal; 3.++signal; //skip code 4.int signal_index = smeta->indexOfSignal(signal); 5.if (signal_index < 0) { 6. // check for normalized signatures 7. tmp_signal_name = QMetaObject: : normalizedSignature(signal - 1); 8. signal = tmp_signal_name.constData() + 1; 9. 10. signal_index = smeta->indexOfSignal(signal); 11. if (signal_index < 0) { 12. err_method_notfound(sender, signal_arg, "connect"); 13. err_info_about_objects("connect", sender, receiver); 14. return false; 15. } 16.} 获取signal的索引。 metaObject()是在moc_name.cpp文件中生成的。 [cpp] viewplaincopy 1.return QObject: : d_ptr->metaObject ? QObject: : d_ptr->metaObject : &staticMetaObject; 其中staticMetaObject也是在moc文件中定义的 [cpp] viewplaincopy 1.const QMetaObject MainWindow: : staticMetaObject = { 2. { &QMainWindow: : staticMetaObject, qt_meta_stringdata_MainWindow, 3. qt_meta_data_MainWindow, 0 } 4.}; qt_meta_stringdata_MainWindow(具
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- QT connect函数的用法 connect 函数 用法