什么是信号和槽

Posted on Wed, 25 Dec 2024 16:06:42 +0800 by LiangMingJian


概述

信号和槽机制是 QT 的核心机制,其是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性,也是 QT 区别于其它工具包的重要地方。信号和槽是 QT 自行定义的一种通信机制,它独立于标准的 C/C++ 语言,因此要正确的处理信号和槽,必须借助一个称为 moc ( Meta Object Compiler ) 的 QT 工具,该工具是一个 C++ 预处理程序,它为高层次的事件处理自动生成所需要的附加代码。

在其它的 GUI 工具包中,窗口部件 widget 都有一个回调函数用于响应它们能触发的每个动作,这个回调函数通常是一个指向某个函数的指针。在 QT 中信号和槽取代了这些凌乱的函数指针,使得我们编写这些通信程序更为简洁明了。信号和槽能携带任意数量和任意类型的参数,且其的类型是完全安全的,不会像回调函数那样产生 core dumps。

所有从 QObject 或其子类 ( 例如 Qwidget )派生的类都能够包含信号和槽。当对象改变其状态时,信号就由该对象发射出去,这就是对象所要做的全部事情,它不需要知道另一端是谁在接收这个信号。这也就是真正的信息封装,它确保对象被当作一个真正的软件组件来使用。槽用于接收信号,主要是普通的对象成员函数,同样的一个槽并不知道是否有任何信号与自己相连接。

信号与槽的关联

通过调用 QObject 对象的 connect 函数来将某个对象的信号与另外一个对象的槽函数相关联,这样当发射者发射信号时,接收者的槽函数将被调用。该函数的定义如下:

bool QObject::connect( const QObject * sender, const char * signal, const QObject * receiver, const char * member ) [static]

connect 函数将信号发送者 sender 对象中的信号 signal 与接受者 receiver 中的 member 槽函数联系起来。注意的是,当指定信号 signal 时必须使用宏 SIGNAL,当指定槽函数时必须使用宏 SLOT。

例如,下面定义了两个对象:标签对象 label 和滚动条对象 scroll,并将 valueChanged() 信号与标签对象的 setNum() 相关联,另外信号还携带了一个整形参数,这样标签总是显示滚动条所处位置的值。

QLabel  *label  = new QLabel; 
QScrollBar  *scroll = new QScrollBar; 
QObject::connect( scroll, SIGNAL(valueChanged(int)), label,  SLOT(setNum(int)) );

当信号与槽没有必要继续保持关联时,我们可以使用 disconnect 函数来断开发射者中的信号与接收者中的槽函数之间的关联。其定义如下:

bool QObject::disconnect( const QObject * sender, const char * signal, const Object * receiver, const char * member ) [static]