函数原型
1 | QMetaObject::Connection QObject::connect( const QObject* sender, const char * signal , const QObject* reciver, const char * method, Qt::ConnectionType type=Qt::AutoConnection) |
创建一个从发送方指定信号到接收方方法的链接,返回链接的句柄,可以用于断开链接。可以通过转换为bool值来判断Connecton是否有效。
发送方的信号和接收方的方法(槽)都是以字符指针的形式传递进来的,可以通过两个宏SIGNAL(), SLOT()将指定的信号和槽转换为字符指针形式。
例如:
1 QLabel *label = new QLabel; 2 QScrollBar *scrollBar = new QScrollBar; 3 QObject::connect(scrollBar, SIGNAL(valueChanged(int)), 4 label, SLOT(setNum(int)));
信号和槽的参数中只能指定参数类型,不可以包含参数名字,以下的方法就是错误的:
1 | // WRONG |
2 | QObject::connect(scrollBar, SIGNAL(valueChanged( int value)), |
3 | label, SLOT(setNum( int value))); |
一个信号可以连接到多个信号和槽,多个信号也可以连接到一个槽。如果一个信号连接到多个槽,当信号产生时,槽被激活的顺序与连接被创建的顺序相同。
可以通过disconnect()函数来断开连接。
connect方法的最后一个参数类型是ConnectionType,这是一个枚举类型,包含以下字段:
字段
|
值
|
描述
|
Qt::AutoConnection
|
0
|
(默认值)如果信号的发射与接收方在不同线程,则与Qt::QueuedConnection行为一致;否则,直接调用槽,行为与Qt::DirectConnection一致。连接类型在信号被发射时确定
|
Qt::DirectConnection
|
1
|
信号被发射时,立即调用槽函数
|
Qt::QueuedConnection
|
2
|
当接收方的消息循环得到控制权时,槽函数才会被调用;槽函数在接收方的线程中执行
|
Qt::BlockingQueuedConnection
|
3
|
与Qt::QueuedConnection行为一致,但是当前线程是阻塞的。这种连接类型只能被用接收方与发送方处于不同线程的情形下。
|
Qt::UniqueConnection
|
0x80
|
这个标志可以与上面三个中的任意一个组合。当此标志被设置时,如果Connection已经存在(同一个信号连接到同一个对象的同一个槽),则connect函数会失败
|
在使用QueuedConnection时,参数必须要在Qt的元对象系统中注册,否则会返回错误信息:
QObject::connect: Cannot queue arguments of type 'MyType' (MyType是你自定义的类型)
因为Qt需要复制参数到后台消息队列中存储,所以在使用自定义连接类型时需要调用qRegisterMetaType()函数来注册。
看 到这里,做过Win32开发的人,就会觉得很熟悉了。是的,就是PostMessage, SendMessage。Qt中Connection的DirectConnection类型对应了 SendMessageTimeOut,QueuedConnection类型对应了 PostMessage,BlockingQueuedConnection类型对应了SendMessage。在做Win32开发时,需要注册窗口类, 系统才会为其维护一个后台消息队列,只有具有后台消息队列的对象才可以处理PostMessage,SendMessage消息,而Qt中的 qRegisterMetaType()函数,毫无疑问就是充当了这个角色。
Win32 SDK是以消息的形式来响应用户事件的,无论怎么变,怎么改名词,信号,槽等等,“消息”这个核心是改变不了的。