画布信号和槽Word文档格式.docx
- 文档编号:21052697
- 上传时间:2023-01-27
- 格式:DOCX
- 页数:19
- 大小:131.36KB
画布信号和槽Word文档格式.docx
《画布信号和槽Word文档格式.docx》由会员分享,可在线阅读,更多相关《画布信号和槽Word文档格式.docx(19页珍藏版)》请在冰豆网上搜索。
∙QCanvasSpline--多重贝塞尔曲线。
∙QCanvasSprite--活动的图片。
∙QCanvasText--文本字符串。
QCanvasPixmap和QCanvasPixmapArray这两个类是由QCanvasSprite类来显示在画布上的活动和移动的图片。
更多的专门的项能够通过继承画布项类来实现。
从一个QCanvasItem的派生类(通常为QCanvasPolygonalItem)来实现比直接从QCanvasItem继承更容易。
QCanvasRectangleClassReference
[canvasmodule]
TheQCanvasRectangleclassprovidesarectangleonaQCanvas.More...
#include<
qcanvas.h>
InheritsQCanvasPolygonalItem.
Listofallmemberfunctions.
PublicMembers
∙QCanvasRectangle(QCanvas
*
canvas)
∙QCanvasRectangle(const
QRect
&
r,QCanvas
∙QCanvasRectangle(int
x,int
y,int
width,int
height,QCanvas
∙~QCanvasRectangle()
∙intwidth()const
∙intheight()const
∙voidsetSize(int
height)
∙QSizesize()const
∙QRectrect()const
∙virtualintrtti()const
ProtectedMembers
∙virtualvoiddrawShape(QPainter
p)
∙virtualQPointArraychunks()const
DetailedDescription
TheQCanvasRectangleclassprovidesarectangleonaQCanvas.
Thisitempaintsasinglerectanglewhichmayhaveanypen()andbrush(),butmaynotbetilted/rotated.Forrotatedrectangles,useQCanvasPolygon.
Therectangle'
ssizeandinitialpositioncanbesetintheconstructor.ThesizecanbesetorchangedlaterusingsetSize().Useheight()andwidth()toretrievetherectangle'
sdimensions.
TherectanglecanbedrawnonapainterwithdrawShape().
LikeanyothercanvasitemrectanglescanbemovedwithQCanvasItem:
:
move()andQCanvasItem:
moveBy(),orbysettingcoordinateswithQCanvasItem:
setX(),QCanvasItem:
setY()andQCanvasItem:
setZ().
SeealsoGraphicsClassesandImageProcessingClasses.
MemberFunctionDocumentation
QCanvasRectangle:
QCanvasRectangle(QCanvas
canvas)
Constructsarectangleatposition(0,0)withbothwidthandheightsetto32pixelsoncanvas.
QCanvasRectangle(const
Constructsarectanglepositionedandsizedbyroncanvas.
QCanvasRectangle(int
Constructsarectangleatposition(x,y)andsizewidthbyheight,oncanvas.
~QCanvasRectangle()
Destroystherectangle.
QPointArrayQCanvasRectangle:
chunks()const[virtualprotected]
SimplycallsQCanvasItem:
chunks().
voidQCanvasRectangle:
drawShape(QPainter
p)[virtualprotected]
Drawstherectangleonpainterp.
Example:
canvas/canvas.cpp.
ReimplementedfromQCanvasPolygonalItem.
intQCanvasRectangle:
height()const
Returnstheheightoftherectangle.
QRectQCanvasRectangle:
rect()const
Returnstheinteger-convertedx(),y()positionandsize()oftherectangleasaQRect.
rtti()const[virtual]
Returns5(QCanvasItem:
Rtti_Rectangle).
SeealsoQCanvasItem:
rtti().
setSize(int
height)
Setsthewidthandheightoftherectangle.
QSizeQCanvasRectangle:
size()const
Returnsthewidth()andheight()oftherectangle.
Seealsorect()andsetSize().
width()const
Returnsthewidthoftherectangle.
槽就是一个返回值为void的函数。
信号和槽机制是类型安全的,一个信号的签名必须与它的接收槽的签名相匹配,这样编译器就可以帮助我们检查类型是否匹配。
信号和槽可以使用任何数量、类型的参数。
QT的窗口部件已经有很多预定义的信号,也有很多预定义的槽,但我们总是通过继承来加入我们自己的信号和自己的槽,这样我们就可以处理感兴趣的信号了。
凡是从QObject类或者它的某个子类继承的所有类都可以包含信号和槽。
当某个事件发生后,被指定的信号就会被发射,它不知道也没有必要知道是否有槽连接了该信号,这就是信息封装。
下面看看不使用信号和槽和使用信号和槽的两个对象有什么不同。
不使用信号和槽的C++对象:
classNoSignalClass{
public:
NoSignalClass(void){}
intvalue(void)const{return_value;
}
intsetValue(intvalue){_value=value;
private:
int_value;
使用信号和槽的QT对象:
classUseSignalClass{
Q_OBJECT
UseSignalClass(void){}
publicslots:
signals:
voidvalueChanged(int);
这两个类有相同的内部状态,相同的公有方法,但后一个类却支持使用信号和槽的组件编程:
这个类可以通过发射一个信号(valueChanged())来告诉外界它的状态发生了变化,并且它有一个槽,可以接收信号。
所有包含信号和槽的类都必须在它们的声明中提到Q_OBJECT。
槽要由自己来实现,这里最好把intsetValue(intvalue)槽这样实现:
voidUseSignalClass:
setValue(intvalue)
{
if(value!
=_value){
_val=value;
emitvalueChanged(value);
}
emitvalueChanged(value);
这行代码是发射一个信号valueChanged。
要想使一个槽在一个信号被发射后被执行,要显示地进行连接:
UseSignalClassa,b;
connect(&
a,SIGNAL(valueChanged(int)),&
b,SLOT(setValue(int)));
这样做后,就把对象a的信号valueChanged和对象b的槽setValue连接了起来,当a的信号valueChanged被发射后,对象b的槽setValue马上就被执行。
执行以下这句代码:
b.setValue(10);
这句被执行后,对象b的valueChanged信号会被发射,但没有槽和该信号相连,所以什么也没做,信号被丢弃。
a.setValue(80);
这句被执行后,对象a的valueChanged信号会被发射,该信号有槽(对象b的setValue)相连,所以b.setValue(int)马上被执行,且参数为80,所以b.value()的值为80。
如果要解除已经建立好连接的信号和槽,可以使用disconnect()函数。
boolQObject:
disconnect(constQObject*sender,constchar*signal,
constObject*receiver,constchar*member)[static]
这个函数断开发射者中的信号和接收者中的槽函数之间的关联。
有以下三种情况:
1、断开某个对象与其它对象的任何连接:
disconnect(object,0,0,0);
或object->
disconnect();
2、断开某个信号与其它任何槽的连接:
disconnect(object,SIGNAL(signal()),0,0);
disconnect(SIGNAL(signal()));
3、断开两个对象之间的任何关联:
disconnect(object,0,receiver,0);
disconnect(receiver);
在disconnect函数中0可以用作一个通配符,可分别表示任何信号、任何接收对象、接收对象中的任何槽函数。
但是发射者不能为0,其它三个参数都可以为0。
关键字signals指出随后开始信号的声明,这里signals用的是复数形式而非单数,siganls没有public、private、protected等属性,这点不同于slots。
另外,signals、slots关键字是QT自己定义的,不是C++中的关键字。
这个例子说明,采用QT的信号和槽机制后,对象之间可以在相互不知道的情况下一起工作,只要在最初的时候在他们中间建立了连接。
槽也是普通的C++函数,可以一样被调用,他唯一的特点就是他们可以被信号连接。
因为槽就是普通的成员函数,它们也和普通的成员函数一样有访问权限,一个槽的访问权限决定了哪些信号可以和它相连接,而信号就没有访问权限的概念。
一个publicslots:
区包含了任何信号都可以相连的槽。
你生成了许多对象,它们互相并不知道,把它们的信号和槽连接起来,这样信息就可以正确地传递,并且就像一个铁路模型,把它打开然后让它跑起来。
一个protectedslots:
区包含了之后这个类和它的子类的信号才能连接的槽。
这就是说这些槽只是类的实现的一部分,而不是它和外界的接口。
一个privateslots:
区包含了之后这个类本身的信号可以连接的槽。
这就是说它和这个类是非常紧密的,甚至它的子类都没有获得连接权利这样的信任。
也可以把槽定义为虚函数,这也很有用。
使用信号和槽机制,要注意以下问题:
1、信号和槽的机制是非常有效的,但是它不像“真正的”回调那样快。
信号和槽稍微有些慢,这是因为它们所提供的灵活性。
但这种损失相对来说是比较小的。
但要追求高效率的话,比如在实时系统中就要尽量少用这种机制。
2、信号和槽机制与普通函数的调用一样,如果使用不当的话,在程序执行时有可能形成死循环,所以,在定义槽函数时一定要注意避免间接形成无限循环,即在槽中再次发射所接收到的同样的信号。
3、如果一个信号和多个槽相关联的话,那当这个信号被发射时,与之相关联的槽的执行顺序将是髓机的,且顺序不能指定。
4、宏定义不能用在signal和slot的参数中。
5、构造函数不能用在signals和slots声明区域内。
6、函数指针不能作为信号或槽的参数。
7、信号和槽不能有缺省参数值。
8、信号和槽不能携带模板类参数。
9、嵌套的类不能位于信号和槽区域内,也不能有信号或者槽。
10、友元声明不能位于信号和槽的声明区域内。
信号和槽
信号和槽用于对象间的通讯。
信号/槽机制是Qt的一个中心特征并且也许是Qt与其它工具包的最不相同的部分。
在图形用户界面编程中,我们经常希望一个窗口部件的一个变化被通知给另一个窗口部件。
更一般地,我们希望任何一类的对象可以和其它对象进行通讯。
例如,如果我们正在解析一个XML文件,当我们遇到一个新的标签时,我们也许希望通知列表视图我们正在用来表达XML文件的结构。
较老的工具包使用一种被称作回调的通讯方式来实现同一目的。
回调是指一个函数的指针,所以如果你希望一个处理函数通知你一些事件,你可以把另一个函数(回调)的指针传递给处理函数。
处理函数在适当的时候调用回调。
回调有两个主要缺点。
首先他们不是类型安全的。
我们从来都不能确定处理函数使用了正确的参数来调用回调。
其次回调和处理函数是非常强有力地联系在一起的,因为处理函数必须知道要调用哪个回调。
一个关于一些信号和槽连接的摘要图
在Qt中我们有一种可以替代回调的技术。
我们使用信号和槽。
当一个特定事件发生的时候,一个信号被发射。
Qt的窗口部件有很多预定义的信号,但是我们总是可以通过继承来加入我们自己的信号。
槽就是一个可以被调用处理特定信号的函数。
Qt的窗口部件又很多预定义的槽,但是通常的习惯是你可以加入自己的槽,这样你就可以处理你所感兴趣的信号。
信号和槽的机制是类型安全的:
一个信号的签名必须与它的接收槽的签名相匹配。
(实际上一个槽的签名可以比它接收的信号的签名少,因为它可以忽略额外的签名。
)因为签名是一致的,编译器就可以帮助我们检测类型不匹配。
信号和槽是宽松地联系在一起的:
一个发射信号的类不用知道也不用注意哪个槽要接收这个信号。
Qt的信号和槽的机制可以保证如果你把一个信号和一个槽连接起来,槽会在正确的时间使用信号的参数而被调用。
信号和槽可以使用任何数量、任何类型的参数。
它们是完全类型安全的:
不会再有回调核心转储(coredump)。
从QObject类或者它的一个子类(比如QWidget类)继承的所有类可以包含信号和槽。
当对象改变它们的状态的时候,信号被发送,从某种意义上讲,它们也许对外面的世界感兴趣。
这就是所有的对象通讯时所做的一切。
它不知道也不注意无论有没有东西接收它所发射的信号。
这就是真正的信息封装,并且确保对象可以用作一个软件组件。
一个信号和槽连接的例子
槽可以用来接收信号,但它们是正常的成员函数。
一个槽不知道它是否被任意信号连接。
此外,对象不知道关于这种通讯机制和能够被用作一个真正的软件组件。
你可以把许多信号和你所希望的单一槽相连,并且一个信号也可以和你所期望的许多槽相连。
把一个信号和另一个信号直接相连也是可以的。
(这时,只要第一个信号被发射时,第二个信号立刻就被发射。
总体来看,信号和槽构成了一个强有力的组件编程机制。
一个小例子
一个最小的C++类声明如下:
classFoo
{
public:
Foo();
intvalue()const{returnval;
voidsetValue(int);
private:
intval;
};
一个小的Qt类如下:
classFoo:
publicQObject
publicslots:
signals:
voidvalueChanged(int);
这个类有同样的内部状态,和公有方法来访问状态,但是另外它也支持使用信号和槽的组件编程:
这个类可以通过发射一个信号,valueChanged(),来告诉外面的世界它的状态发生了变化,并且它有一个槽,其它对象可以发送信号给这个槽。
所有包含信号和/或者槽的类必须在它们的声明中提到Q_OBJECT。
槽可以由应用程序的编写者来实现。
这里是Foo:
setValue()的一个可能的实现:
voidFoo:
setValue(intv)
if(v!
=val){
val=v;
emitvalueChanged(v);
emitvalueChanged(v)这一行从对象中发射valueChanged信号。
正如你所能看到的,你通过使用emitsignal(arguments)来发射信号。
下面是把两个对象连接在一起的一种方法:
Fooa,b;
connect(&
b.setValue(11);
//a==undefinedb==11
a.setValue(79);
//a==79b==79
b.value();
调用a.setValue(79)会使a发射一个valueChanged()信号,b将会在它的setValue()槽中接收这个信号,也就是b.setValue(79)被调用。
接下来b会发射同样的valueChanged()信号,但是因为没有槽被连接到b的valueChanged()信号,所以没有发生任何事(信号消失了)。
注意只有当v!
=val的时候setValue()函数才会设置这个值并且发射信号。
这样就避免了在循环连接的情况下(比如b.valueChanged()和a.setValue()连接在一起)出现无休止的循环的情况。
这个例子说明了对象之间可以在互相不知道的情况下一起工作,只要在最初的时在它们中间建立连接。
预处理程序改变或者移除了signals、slots和emit这些关键字,这样就可以使用标准的C++编译器。
在一个定义有信号和槽的类上运行moc。
这样就会生成一个可以和其它对象文件编译和连接成引用程序的C++源文件。
信号
信号会由moc自动生成并且一定不要在.cpp文件中实现。
它们也不能有任何返回类型(比如使用void)。
关于参数需要注意。
我们的经验显示如果信号和槽不使用特殊的类型,它们都可以多次使用。
如果QScrollBar:
valueChanged()使用了一个特殊的类型,比如
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 画布 信号