导言:
Qt的信号号和槽 (Signal&Slots)是Qt的特性,深入理解该机制是能够精通Qt编程的关键。
信号号和槽 (Signal&Slots)的作用:
信号和槽用于两个对象之间的通信。
常见的如:Qt的部件类(l例如:Widget)中定义了一些信号和槽,一般的操作是子类化这个部件,然后添加自己的信号和槽来实现想要的功能。
信号号和槽 (Signal&Slots)机制与回调函数的区别:
回调函数是指向函数的指针,把这个回调函数指针传递给要被处理的函数,那么就可以在这个函数被处理时在适当的地方调用这个回调函数。
信号和槽的机制,一个信号可以关联到多个槽上,多个信号也可以关联到同一个槽上,甚至,一个信号还可以关联到另一个信号上。
信号和槽的运用:
定义信号
例如:
signals:
void dlgReturn(int); //自定义的信号
说明:
1、声明一个信号要使用signals关键字
2、在signals 前面不能使用public、private和protected等限定符,因为只有定义了该信号的类及其子类才可以发射该信号。
3、而且信号只用声明,不需要也不能对它进行定义实现。
4、信号没有返回值,只能用void类型。
5、使用信号和槽,还需要在类声明的最开始处添加Q_OBJECT宏。
定义槽:
例如:
private slots:
void showValue(int value);
说明:
1、声明一个槽需要使用slot关键字。
2、一个槽可以是private\public\或者protected类型。
3、槽也是可以声明为虚函数。
信号和槽关联函数:
bool QObject::connect(const QObject *sender, const char * signal, const QObject *receiver, const char *method, Qt::ConnectionType type = AutoConnection )
一个控制台实现connect连接信号和槽的实例
目标:通过该实例实现对象间的简单通信。
首先定义一个类Foo
1、设置两个私有变量val,area。 同时可以通过公有函数value()、getArea()来访问这两个私有变量。
2、定义两个信号 valueChange(int), areaChange(int)
3、定义槽 setValue(int)、circleSolve(int).
#define PI 3.14
class Foo: public QObject
{
Q_OBJECT
public:
Foo();
int value() const{return val;};
double getArea() const {return area;};
public slots:
void setValue(int);
void cirleSolve(int radius);
signals:
void valueChanged(int);
void areaChange(int);
private:
int val;
double area;
};
其次,实现这个类:
Foo::Foo()
{
}
//更新val 值,并发送值更改单哦信号
void Foo::setValue(int v)
{
if(v!= val)
{
val=v;
emit valueChanged(v);
}
}
//计算圆面积,并发送面积信号
void Foo::cirleSolve(int radius)
{
area = PI*radius*radius;
emit areaChange(radius);
}
接着,在main()关联 并测试,这里做了三项内容
1、建立对象c、b
2、将c对象的操作与b对象的槽相关联。
这样当c对象调用setValue()、circleSolve()函数将会影响b的私有变量。
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Foo c,b;
QObject::connect(&c,SIGNAL(valueChanged(int)),&b,SLOT(setValue(int)));
QObject::connect(&c,SIGNAL(areaChange(int)),&b,SLOT(cirleSolve(int )));
c.cirleSolve(6);
cout<<"the circle area of b: "<<b.getArea()<<endl;
b.setValue(8);
cout<<"the testValue of b is :"<<b.value()<<endl;
cout<<"the testValue of c is :"<<c.value()<<endl;
c.setValue(5);
cout<<"the testValue of b is :"<<b.value()<<endl;
cout<<"the testValue of c is :"<<c.value();
return a.exec();
}
信号和槽的使用总结:
1、定义信号和槽
2、关联
在适当的时候发送信号
3、使用要点:
需要继承QObject或其子类
在类声明的最开始添加QOBject 宏
槽中的参数类型要和信号的参数类型对应。
信号只用声明,且返回值为void的类型。