Qt图形编程基础之:Qt/Embedded开发入门
2.信号与插槽实现实例
(1)信号。
当某个信号对其客户或所有者内部状态发生改变时,信号就被一个对象发射。只有定义了这个信号的类及其派生类才能够发射这个信号。当一个信号被发射时,与其相关联的插槽将被立刻执行,就像一个正常的函数调用一样。信号-插槽机制完全独立于任何GUI事件循环。只有当所有的槽返回以后发射函数(emit)才返回。如果存在多个槽与某个信号相关联,那么,当这个信号被发射时,这些槽将会一个接一个地执行,但是它们执行的顺序将会是随机的、不确定的,用户不能人为地指定哪个先执行、哪个后执行。
Qt的signals关键字指出进入了信号声明区,随后即可声明自己的信号。例如,下面定义了3个信号:
signals:
voidmySignal();
voidmySignal(intx);
voidmySignalParam(intx,inty);
在上面的定义中,signals是Qt的关键字,而非C/C++的。接下来的一行voidmySignal()定义了信号mySignal,这个信号没有携带参数;接下来的一行voidmySignal(intx)定义了重名信号mySignal,但是它携带一个整形参数,这有点类似于C++中的虚函数。从形式上讲信号的声明与普通的C++函数是一样的,但是信号却没有函数体定义。另外,信号的返回类型都是void。信号由moc自动产生,它们不应该在.cpp文件中实现。
(2)插槽。
插槽是普通的C++成员函数,可以被正常调用,它们惟一的特殊性就是很多信号可以与其相关联。当与其关联的信号被发射时,这个插槽就会被调用。插槽可以有参数,但插槽的参数不能有缺省值。
插槽是普通的成员函数,因此与其他的函数一样,它们也有存取权限。插槽的存取权限决定了谁能够与其相关联。同普通的C++成员函数一样,插槽函数也分为3种类型,即publicslots、privateslots和protectedslots。
n publicslots:在这个区内声明的槽意味着任何对象都可将信号与之相连接。这对于组件编程非常有用,用户可以创建彼此互不了解的对象,将它们的信号与槽进行连接以便信息能够正确地传递。
n protectedslots:在这个区内声明的槽意味着当前类及其子类可以将信号与之相连接。这适用于那些槽,它们是类实现的一部分,但是其界面接口却面向外部。
n privateslots:在这个区内声明的槽意味着只有类自己可以将信号与之相连接。这适用于联系非常紧密的类。
插槽也能够被声明为虚函数,这也是非常有用的。插槽的声明也是在头文件中进行的。例如,下面声明了3个插槽:
publicslots:
voidmySlot();
voidmySlot(intx);
voidmySignalParam(intx,inty);
(3)信号与插槽关联。
通过调用QObject对象的connect()函数可以将某个对象的信号与另外一个对象的插槽函数或信号相关联,当发射者发射信号时,接收者的槽函数或信号将被调用。
该函数的定义如下所示:
boolQObject::connect(constQObject*sender,constchar*signal,constQObject*receiver,constchar*member)[static]
这个函数的作用就是将发射者sender对象中的信号signal与接收者receiver中的member插槽函数联系起来。当指定信号signal时必须使用Qt的宏SIGNAL(),当指定插槽函数时必须使用宏SLOT()。如果发射者与接收者属于同一个对象的话,那么在connect()调用中接收者参数可以省略。
n 信号与插槽相关联。
下例定义了两个对象:标签对象label和滚动条对象scroll,并将valueChanged()信号与标签对象的setNum()插槽函数相关联,另外信号还携带了一个整型参数,这样标签总是显示滚动条所处位置的值。
QLabel*label=newQLabel;
QScrollBar*scroll=newQScrollBar;
QObject::connect(scroll,SIGNAL(valueChanged(int)),label,SLOT(setNum(int)));
n 信号与信号相关联。
在下面的构造函数中,MyWidget创建了一个私有的按钮aButton,按钮的单击事件产生的信号clicked()与另外一个信号aSignal()进行关联。这样,当信号clicked()被发射时,信号aSignal()也接着被发射。如下所示:
classMyWidget:publicQWidget
{
public:
MyWidget();
...
signals:
voidaSignal();
...
private:
...
QPushButton*aButton;
};
MyWidget::MyWidget()
{
aButton=newQPushButton(this);
connect(aButton,SIGNAL(clicked()),SIGNAL(aSignal()));
}
(4)解除信号与插槽关联。
当信号与槽没有必要继续保持关联时,用户可以使用disconnect()函数来断开连接。其定义如下所示:
boolQObject::disconnect(constQObject*sender,constchar*signal,constObject*receiver,constchar*member)[static]
这个函数断开发射者中的信号与接收者中的槽函数之间的关联。
有3种情况必须使用disconnect()函数。
n 断开与某个对象相关联的任何对象。
当用户在某个对象中定义了一个或者多个信号,这些信号与另外若干个对象中的槽相关联,如果想要切断这些关联的话,就可以利用这个方法,非常简洁。如下所示:
disconnect(myObject,0,0,0)
或者
myObject->disconnect()
n 断开与某个特定信号的任何关联。
这种情况是非常常见的,其典型用法如下所示:
disconnect(myObject,SIGNAL(mySignal()),0,0)
或者
myObject->disconnect(SIGNAL(mySignal()))
n 断开两个对象之间的关联。
这也是非常常用的情况,如下所示:
disconnect(myObject,0,myReceiver,0)
或者
myObject->disconnect(myReceiver)
注意 | 在disconnect()函数中0可以用作一个通配符,分别表示任何信号、任何接收对象、接收对象中的任何槽函数。但是发射者sender不能为0,其他3个参数的值可以等于0。 |
linux相关文章:linux教程
评论