一个事实:
在实际的项目开发中,大多数时候是直接将组件中预定义信号连接到槽函数
Qt中信号(Signal)
信号只是一个特殊的成员函数声明
1. 函数的返回值是void类型
2. 函数只能声明不能定义
信号必须使用signals关键字进行声明
1. 函数的访问属性自动被设置为protected
2. 只能通过emit关键字发送信号
示例:
class Test : public QObject //必须继承自QObject
{
Q_OBJECT //必须在私有区声明Q_OBJECT宏
signals: //使用signals声明信号函数
void testSignal(int v); //信号只能声明不能定义
public:
void send(int i)
{
emit testSignal(i); //使用关键字emit发送信号
}
};
信号与槽的对应关系
一个信号可以连接到多个槽(一对多)
多个信号可以连接到一个槽(多对一)
一个信号可以连接到另一个信号(转嫁)
连接可以被disconnect()函数删除(移除)
其他几个注意点:
信号类只能在头文件中声明
信号与槽原型应该完全相同
不相同时,如果信号的参数多于槽参数,多于的参数将被忽略
槽函数的返回值必须是void类型
槽函数可以像普通成员函数一样被调用
信号与槽的访问属性多于connect() / disconnect()无效
信号与槽的意义
最大限度的弱化了类之间的耦合关系,提高了类的可复用性
再设计阶段,可以减少不必要的接口类(抽象类)
在开发阶段,对象间的交互通过信号与槽动态绑定
//TestSignal.h
#ifndef TESTSIGNAL_H
#define TESTSIGNAL_H
#include <QObject>
class TestSignal : public QObject
{
Q_OBJECT
public:
void send(int i)
{
emit testSignal(i); //发送信号
}
signals:
void testSignal(int v); //信号声明
};
#endif // TESTSIGNAL_H
//RxClass.h
#ifndef RXCLASS_H
#define RXCLASS_H
#include <QObject>
#include <QDebug>
class RxClass : public QObject
{
Q_OBJECT
public:
protected slots:
void mySlot(int v)
{
qDebug() << "void mySlot(int v)";
qDebug() << "Sender: " << sender()->objectName();
qDebug() << "Receiver: " << this->objectName();
qDebug() << "Value: " << v;
qDebug() << endl;
}
};
#endif // RXCLASS_H
//main.cpp
#include <QtCore/QCoreApplication>
#include <QDebug>
#include "TestSignal.h"
#include "RxClass.h"
void emit_signal()
{
qDebug() << "emit_signal()" << endl;
TestSignal t;
RxClass r;
t.setObjectName("t");
r.setObjectName("r");
QObject::connect(&t, SIGNAL(testSignal(int)), &r, SLOT(mySlot(int)));
for(int i=0; i<3; i++)
{
t.send(i);
}
}
void one_to_multi()
{
qDebug() << "one_to_multi()" << endl;
TestSignal t;
RxClass r1;
RxClass r2;
t.setObjectName("t");
r1.setObjectName("r1");
r2.setObjectName("r2");
QObject::connect(&t, SIGNAL(testSignal(int)), &r1, SLOT(mySlot(int)));
QObject::connect(&t, SIGNAL(testSignal(int)), &r2, SLOT(mySlot(int))); //一对多
t.send(100);
}
void multi_to_one()
{
qDebug() << "multi_to_one()" << endl;
TestSignal t1;
TestSignal t2;
RxClass r;
t1.setObjectName("t1");
t2.setObjectName("t2");
r.setObjectName("r");
QObject::connect(&t1, SIGNAL(testSignal(int)), &r, SLOT(mySlot(int)));
QObject::connect(&t2, SIGNAL(testSignal(int)), &r, SLOT(mySlot(int))); //多对一
t1.send(101);
t2.send(102);
}
void signal_to_signal()
{
qDebug() << "signal_to_signal()" << endl;
TestSignal t1;
TestSignal t2;
RxClass r;
t1.setObjectName("t1");
t2.setObjectName("t2");
r.setObjectName("r");
QObject::connect(&t1, SIGNAL(testSignal(int)), &t2, SIGNAL(testSignal(int))); //信号转嫁
QObject::connect(&t2, SIGNAL(testSignal(int)), &r, SLOT(mySlot(int)));
t1.send(101); //t1间接发送信号 间接多对一
t2.send(102);
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// emit_signal();
// one_to_multi();
// multi_to_one();
// signal_to_signal();
return a.exec();
}
声明:
此文根据 狄泰学院唐老师的《QT实验分析教程》创作