Qt的信号和槽
信号和槽是Qt特有的信息传输驱动机制,是Qt程序设计中的重要基础,它可以让程序员在互不相干的对象之间建立联系。
槽本质上是类的成员函数,其参数可以是任意类型,它与普通的C++成员函数几乎没有区别,它可以是虚函数;也可以被重载函数;可以是公有的、保护的或私有的,也可以被其它C++成员函数调用,和普通的类成员函数唯一不同的是:槽还可以和信号连接在一起,每当和槽连接的信号被发射时,就会自动调用这个槽。
connect()语法形式如下:
connect(sender,SIGNAL(signal),receiver,SLOT(slot));
这里的sender是发送信号的对象的指针,receiver是包含槽的对象的指针,signal是被发送的信号,slot是接受信号的槽,他们都是不带参数的函数名。SIGNAL()宏和SLOT()宏会把他们的参数转换成相应的字符串。对于信号和槽,还具有以下特点。
1.一个信号可以连接多个槽
connect(sender,SIGNAL(signal),receiver,SLOT(slotA));
connect(sender,SIGNAL(signal),receiver,SLOT(slotB));
当这一信号发射时,会以不确定的顺序一个接一个的调用这个信号连接的所有槽
2.多个信号可以连接同一个槽
connect(sender,SIGNAL(signalA),receiver,SLOT(slot));
connect(sender,SIGNAL(signalB),receiver,SLOT(slot));
无论哪个信号被发射,这个槽都会被调用
3.一个信号可以连接另外一个信号
connect(sender,SIGNAL(signalA),receiver,SIGNAL(signalB));
当信号A发射时,也会发射与它相连的信号B
4.信号、槽之间的连接可以被移除
disconnect(sender,SIGNAL(signal),receiver,SLOT(slot));
因为删除对象时,Qt会自动移除和这个对象相关的所有连接,所以这个语法很少用到。
除此之外,要把信号成功连接到槽(或者连接到另一个信号),还应该注意,相连接的信号和槽必须具有相同顺序相同类型的参数,如果信号的参数比它所连接的槽的参数多,那么多余的参数将被简单的忽略掉。例如:
connect(sender,SIGNAL(rawCommandReply(int,const QString &)),
receiver,SIGNAL(processReply(int , const QString &)));
如果参数类型不匹配,或者信号或槽不存在,尽管应用程序调试构建可能会通过,但Qt会在运行时发出警告。
如果信号和槽的名字中包含了参数名,也会发生错误警告
实际上这种机制是在QObject中实现的,这表明信号和槽并不仅仅局限于GUI编程中,实际上这种机制可以用于任何QObject的子类中,
在普通的类中使用信号和槽机制
Class Circle:public QObject
{
Q_ONJECT
public:
Circle(){CircleRadius=0;}
int Radius(){return CircleRadius;}
public slots:
void setRadius(int newRadius);
signals:
void radiusChanged(int newRadius);
private:
int circleRadius;
};
void Circle::setRadius(int newRadius)
{
if(newRadius!=circleRadius)
{
circleRadius=newRadius;
emit radiusChanged(circleRadius);
}
}
来看一下,setRadius()槽是如何工作的。
仔细阅读会发现只有在newRadius不等于circleRadius的时候,才会发射radiusChanged()信号。这样既可以确保信号和槽连接又不会导致无限循环。
❤️我的目标是:someday,即便你花钱看我的文章,也会觉得心满意足