qtgraphicsview框架中实现多个item之间的层次调整功能_第1页
qtgraphicsview框架中实现多个item之间的层次调整功能_第2页
qtgraphicsview框架中实现多个item之间的层次调整功能_第3页
qtgraphicsview框架中实现多个item之间的层次调整功能_第4页
qtgraphicsview框架中实现多个item之间的层次调整功能_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Qt GraphicsView框架中实现多个item之间的层次调整功能目的:要实现 GraphicsView 中多个item 之间的层次调 整功能,即:选中的item可以实现移动至顶层、移动至底 层、上移一层、下移一层”等功能。之前盲目地认为Qt API会提供“获取与之相邻的sibling item ”类似这样的接口, 但是查询无果。setZValue()设置item的栈顺序,通过zValue()来测试,具有低 z-values的item比具有高 z-value 的item 先绘制。(即:低 z-values 的item 位于下层, 高z-values 的item 位于上层)可以调用 setZ

2、value()来设置一个item的Z值。默认的Z值是0 ,具有同样的Z 值的item会按照插入的顺序来入栈 (stack order)。也就是说, GraphicsView 会优先根据item的Z值决定item的层次,只 有当Z值相同的情况下才会去理会stack order ;这样,我就基本上决定放弃采用 setZvalue()方法来实现我的功能了,因为,由于所有item的Z值默认都是0,调用setZvalue()方 法基本上只能实现置于顶层或底层的功能,即使想办法获取 到了与其相邻的上一个或下一个item ,也是需要去设置相关item的Z值,这样一来,维护 tiem的层次的工作完全由自 己来

3、完成了,而不再是 GraphicsSene 自己去根据stackorder去管理维护了,自己的工作量会很大,而且,效率会 比较低下。于是,果断放弃此途径。还是想偷个赖,把item的维护工作依然交给 Scene ,所以通过调整item的stack order来实现上述功能。API有一个stackBefore(QGraphicsItem *sibling) 方法,可以调用该访 求来重新排序item的列表,就可以直接调整item的顺序了。 例如:itemA-stackBefore(itemB) ,是将 itemA 的 order 重置到itemB之前,这样,先绘制itemA,后绘制itemB ,it

4、emB 处于上方。但是,这需要我解决“获取 sibling item ”的工作, 还好问题不大,QGraphicsScene 类方法 collidingItems(QGraphicsItem *item) 会返回一个在这个 Scene中与传入的item有碰撞的所有其它item的一个列表 QList,注意一下,这个列表是不包含item本身的,而且以是自上层向下层的顺序来返回的。于是,自己写了一个算法,以获取当前item在所有冲撞items中的位置,如 下所示: cpp:nogutter viewplaincopyintQDrawGraphicsScene二getItemIndex(QGraphi

5、csItem*item) /list1是与item碰撞的其它item列表 QList list1 =collidingItems(item);没有碰撞if (list1.size() = 0) return 0;/只有一个与之碰撞if (list1.size() = 1)共 2 层(QRectFrect1(item-mapToScene(item-boundingRect().bou ndingRect();QRectFrect2(list1.first()-mapToScene(list1.first()-bounding Rect().boundingRect();QRectF rectM

6、ix = ersected(rect2);QPointFpoint(item-mapFromScene(rectMix).boundingRect().ce nter();QRectF rect(point.x()-0.5, point.y()-0.5, 1, 1);if (item-isObscured(rect)return 1;/item为下层(共2层)elsereturn 0;/item为顶层(共2层)/ist2是与listl末点碰撞的其它item列表QList list2 = collidingItems(list1.last();if (list1.first()

7、 != list2.first()与之碰撞 2 个以上,且 item位于顶层return 0;else/ist3是与list1起点碰撞的其它item列表QList list3 = collidingItems(list1.first();return (list3.indexOf(item) + 1);返回该item的具体位置) 算法中的难点是只有两层(即list1.size()为1)的时候判断 哪个item在上,哪个在下,为此费尽周折,最终采用碰撞混和区域是否被覆盖的方法来实现判断两个item的上下关系。(完全使用碰撞混和区域会由问题,是因为转换后的区域并未完全覆盖,通过查看源码,覆盖判断很

8、严格,所以取了混和 区域的一个中心小区域进行判断,呃。 。汗一把ToT)注意: 为了便于表达,此函数返回的值是该item在与其他碰撞item 共同组成的列表中的位置,即,该 item也是其中之一;而, collidingItems(QGraphicsItem *item)返回的列表是不包含传入进去的item的,了解了这个,下面的调用才不会由问题。 以下是我简单写的一个小demo,以作测试:具体的调用:cpp:nogutter viewplaincopy/ 上移一层void QDrawGraphicsScene:slotLayerUpper() QList collideItems = coll

9、idingItems(itemSelected);if (collideItems.size() = 0)return;int nCurIndex = getItemIndex(itemSelected);if (nCurIndex = 0)return;collideItems.at(nCurIndex -1)-stackBefore(itemSelected);update();下移一层void QDrawGraphicsScene:slotLayerLower()(QList items = selectedItems();QGraphicsItem *itemSelected = it

10、ems.first();QList collideItems = collidingItems(itemSelected);if (collideItems.size() = 0)return;int nCurIndex = getItemIndex(itemSelected);if (nCurIndex = collideItems.size()return;itemSelected-stackBefore(collideItems.at(nCurIndex);update();)置于顶层void QDrawGraphicsScene:slotLayerTop()QList collideltems =collidingltems(itemSelected);for (int i = collideItems.size()-1; i = 0; -i)collideItems.at(i)-stackBefore(itemSelected);update();置于底层void QDrawGraphicsScene:slotLayerBottom()(QList

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论