信号和槽是Qt最为重要的特性之一,它使得对象之间的通信变得简单而高效。在C++中,我们可以用回调函数实现不同对象之间的通信,但是信号和槽更简单易用。
本质上,信号和槽都是函数,信号只能声明,不能提供定义,而槽函数可以,并且槽函数也可以像普通函数一样使用。
Qt很多组件都定义了大量默认的信号和槽,但很多时候我们也需要定义自己的信号和槽函数。
我们使用emit关键字来发出信号,信号被发出后类似于广播,所有组件都将收到该信号,我们需要指定接收该信号的对象,并定义槽函数来处理该信号。
发出信号背后的本质是Qt的事件循环机制,这将在下一节进行总结。
作为一个简单的例子,我们创建两个QWidget,分别命名为w1,w2,看如下示例:
/*部分代码*/
/****************** w1.h ***********************/
Public:
void run( );
signals:
void mySignal_1( QString name );
Private:
QString mName_1;
/****************** w1.cpp***********************/
Constructor{
mName_1 = “MyWidget_1”;
}
void run( )
{
QTimer *timer = new QTimer( this );
Connect(timer,&QTimer::timeout,[=](){
emit mySignal_1( mName_1 );
});
timer_>start( 1000 );
}
/****************** w2.h ***********************/
Private slots:
void getName( QString name );
/****************** w2.cpp***********************/
w1;
w1.run( );
Connect( &w1,&QWidget::MySignal_1,&this,&QWidget::getName);
/****************** main.cpp***********************/
Output:
MyWidget_1;
......
我们在w1中创建了run()函数,一旦w1调用了run()函数,就每隔1秒发出MySignal_1信号。在w2中,连接这个MySignal_1信号,并调用槽函数getName处理这个信号,将w1的名字打印出来。
基于类似的方法,我们可以在任何窗口中获取我们需要知道的其他窗口的信息,只需将其他窗口的参数传出来即可,并在我们想要获取的地方处理它。
需要进一步提到的是,不仅可以用槽函数连接信号,也可以用信号连接信号,即用某个信号触发另一个信号的产生。也可以用多个槽函数连接同一个信号。槽函数的参数可以比信号少,即槽函数可以忽略一部分参数,但是槽函数的参数不能比信号的参数多,因为那样的话,便无法工作;