什么是QT中的信号插槽机制

2024年11月19日 23:20
有1个网友回答
网友(1):

一、信号槽的基本概念
关于QT信号槽的基本概念大家都懂,通过信号槽机制,QT使对象间的通信变得非常简单:
A对象声明信号(signal),B对象实现与之参数相匹配的槽(slot),通过调用connect进行连接,合适的时机A对象使用emit把信号带上参数发射出去,B对象的槽会就接收到响应。

信号槽机制有一些特点:
1. 类型安全:只有参数匹配的信号与槽才可以连接成功(信号的参数可以更多,槽会忽略多余的参数)。
2. 线程安全:通过借助QT自已的事件机制,信号槽支持跨线程并且可以保证线程安全。
3. 松耦合:信号不关心有哪些或者多少个对象与之连接;槽不关心自己连接了哪些对象的哪些信号。这些都不会影响何时发出信号或者信号如何处理。
4. 信号与槽是多对多的关系:一个信号可以连接多个槽,一个槽也可以用来接收多个信号。

使用这套机制,类需要继承QObject并在类中声明Q_OBJECT。下面就对信号槽的实现做一些剖析,了解了这些在使用的时候就不会踩坑喽。
二、信号与槽的定义
槽:用来接收信号,可以被看作是普通成员函数,可以被直接调用。支持public,protected,private修饰,用来定义可以调用连接到此槽的范围。
1. public slots:
2. void testslot(const QString& strSeqId);
信号:只需要声明信号名与参数列表即可,就像是一个只有声明没有实现的成员函数。
1. signals:
2. void testsignal(const QString&);
QT会在moc的cpp文件中实现它(参考下面代码)。下面代码中调用activate的第三个参数是类中信号的序列号。
1. // SIGNAL 0
2. void CTestObject:: testsignal (const QString & _t1)
3. {
4. void *_a[] = { 0, const_cast(reinterpret_cast(&_t1)) };
5. QMetaObject::activate(this, &staticMetaObject, 0, _a);
6. }
三、信号槽的连接与触发
通过调用connect()函数建立连接,会把连接信息保存在sender对象中;调用desconnect()函数来取消。
connect函数的最后一个参数来用指定连接类型(因为有默认,我们一般不填写),后面会再提到它。
1. static bool connect(const QObject *sender, const QMetaMethod &signal,
2. const QObject *receiver, const QMetaMethod &method,
3. Qt::ConnectionType type = Qt::AutoConnection);
一切就绪,发射!在sender对象中调用:
1. emit testsignal(“test”);
1. # define emit
上面代码可以看到emit被定义为空,这样在发射信号时就相当于直接调用QT为我们moc出来的函数testsignal(constQString & _t1)。
具体的操作由QMetaObject::activate()来处理:遍历所有receiver并触发它们的slots。针对不同的连接类型,这里的派发逻辑会有不同。

更多信息请参阅:
http://blog.csdn.net/harbinzju/article/details/10813635