QT入门学习之信 与槽

信 与槽是Qt编程的基础,信 与槽机制让界面各个组件的交互操作时变得更加直观和简单。所有从QObject或其子类(例如Qwidget)派生的类都能够包含信 和槽。当对象改动其状态时,信 就由该对象发射(emit)出去,这就是对象所要做的全部事情,他不知道另一端是谁在接收这个信 。这就是真正的信息封装,他确保对象被当作一个真正的软件组件来使用。槽用于接收信 ,但他们是普通的对象成员函数。一个槽并不知道是否有所有信 和自己相连接。而且,对象并不了解具体的通信机制。你能将非常多信 和单个的槽进行连接,也能将单个的信 和非常多的槽进行连接,甚至于将一个信 和另外一个信 相连接也是可能的,这时无论第一个信 什么时候发射系统都将即时发射第二个信 。总之,信 和槽构造了一个强大的部件编程机制。

1、信 与槽定义及相关基本格式

I、定义
信 (Signal):就是在特定的情况下被发射的事件(如:PushButton最常见的信 是鼠标单击时候发射的click()信 )。当某个信 对其客户或所有者发生的内部状态发生改动,信 被一个对象发射。只有定义过这个信 的类及其派生类能够发射这个信 。当一个信 被发射时,和其相关联的槽将被即时执行,就象一个正常的函数调用相同。信 -槽机制完全独立于所有GUI事件循环。只有当所有的槽返回以后发射函数(emit)才返回。如果存在多个槽和某个信 相关联,那么,当这个信 被发射时,这些槽将会一个接一个地执行。

信 的声明是在头文件中进行的,QT的signals关键字指出进入了信 声明区,随后即可声明自己的信 。例如,下面定义了三个信 :
signals:
void mySignal();
void mySignal(int x);
void mySignalParam(int x,int y);

在上面的定义中,signals是QT的关键字,而非C/C++的。接下来的一行void mySignal() 定义了信 mySignal,这个信 没有携带参数;接下来的一行void mySignal(int x)定义了重名信 mySignal,不过他携带一个整形参数,这有点类似于C++中的虚函数。从形式上讲信 的声明和普通的C++函数是相同的,不过信 却没有函数体定义,另外,信 的返回类型都是void,不要指望能从信 返回什么有用信息。 信 由moc自动产生,他们不应该在.cpp文件中实现。

槽(Slot):就是对信 响应的函数。槽就是一个函数,与一般的C++函数一样,可以定义在类的任何部分(publicprivateprotected),可以具有任何参数,也可以被直接调用。槽函数与一般函数不同在于它与信 关联,当对应的信 发射,关联的槽函数就会自动执行。
public slots:在这个区内声明的槽意味着所有对象都可将信 和之相连接。这对于组件编程非常有用,你能创建彼此互不了解的对象,将他们的信 和槽进行连接以便信息能够正确的传递。
protected slots:在这个区内声明的槽意味着当前类及其子类能将信 和之相连接。这适用于那些槽,他们是类实现的一部分,不过其界面接口却面向外部。
private slots:在这个区内声明的槽意味着只有类自己能将信 和之相连接。这适用于联系非常紧密的类。
槽也能够声明为虚函数,这也是非常有用的。
槽的声明也是在头文件中进行的。例如,下面声明了三个槽:
public slots:
void mySlot();
void mySlot(int x);
void mySignalParam(int x,int y);

注1:使用信 与槽机制,类定义中必须加Q_OBJECT;
注2:signals前面不可加public、private和protected进行修饰;slots前面可以加,因为Qt说槽函数可以当普通函数使用;
注3:signals区域的函数必须是void类型,而且这些信 函数没有函数体,也就是说不可以自己定义这些信 函数,你只要声明它就够了,其它不用管,Qt内部自己弄;
注4:宏定义和函数指针不能用于信 和槽的参数信 和槽也不能有缺省参数;
注5:严格情况下,信 与槽的参数个数和类型需要一致,至少信 的参数不能少于槽的数据。如果不匹配,会出现编译错误或运行错误;
注6:当与信 关联的所有槽函数执行完毕后,才会执行发射信 后面的代码。

II、基本格式
信 与槽关联用QObject类的一个静态函数QObject::connect()实现,一般格式:
QObject::connect(sender,SIGNAL(signal()),receiver,SLOT(slot()));
因为QObject是所有Qt类的基类,实际调用时可以忽略前面的限定符,格式为:
connect(sender,SIGNAL(signal()),receiver,SLOT(slot()));
其中sender是发射信 的对象的名称,signal()是信 名称,信 可以看成是特殊的函数,需要带括 ,有参数时候还需要指明参数。receiver是接收信 的对象名称,slot()是槽函数的名称,需要带括 ,有参数还需要指明参数。
SIGNAL和SLOT都是Qt的宏,指明信 和槽,并将它们的参数转换成字符串。

1)一个信 连接多个槽,格式如下:
connect(sender,SIGNAL(signal()),receiver,SLOT(slot1()));
connect(sender,SIGNAL(signal()),receiver,SLOT(slot2()));
……………………………………………………………………
当发射信 的对象的状态发生改变的时候,发射信 对象发射信 ,接收信 对象关联的不同槽都执行。执行顺序一般按照建立连接时的顺序依次进行。
注:当信 与槽函数带参数时,在connect()函数里要写明参数的类型,但可以不写参数名称。

2)多个信 关联到同一个槽,格式如下:
connect(sender1,SIGNAL(signal()),receiver,SLOT(slot()));
connect(sender2,SIGNAL(signal()),receiver,SLOT(slot()));
……………………………………………………………………
注意:发射的信 可以是由不同发射信 对象发射出的相同类型的信 也可以是不同类型的信 。

3)一个信 关联另一个信 ,格式如下:
connect(sender1,SIGNAL(signal()),receiver,SIGNAL(signal()));
当一个信 发射时另一个信 也发射。

2. 可视化生成槽函数原型和框架

QT入门学习之信 与槽

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年2月15日
下一篇 2019年2月15日

相关推荐