当前位置:   article > 正文

QT图形显示和处理7_qgraphicsscene怎么判断里面是否有图形

qgraphicsscene怎么判断里面是否有图形

再贴一段代码:注意先把上面的代码屏蔽掉:

  1. //坐标系实验
  2. QGraphicsScene *scene = new QGraphicsScene;
  3. MyGraphicsItem *item = new MyGraphicsItem;
  4. scene->addItem(item);
  5. //这个偏移是根据父类的偏移,而不是子类的,
  6. //如果不加后面的 item->setParentItem(rectItem); 父类就是场景scene了,就是根据scene的顶点偏移的。
  7. item->setPos(10, 10);
  8. //item->setZValue(1);
  9. QGraphicsRectItem *rectItem = scene->addRect(QRect(0, 0, 100, 100),
  10. QPen(Qt::blue), QBrush(Qt::green));
  11. item->setParentItem(rectItem);
  12. rectItem->setPos(40, 40);
  13. MyGraphicsView *view = new MyGraphicsView;
  14. view->setScene(scene);
  15. view->setForegroundBrush(QColor(255, 255, 0, 100));
  16. view->setBackgroundBrush(QPixmap("./ShowDebug/2.png"));
  17. view->resize(400, 300);
  18. view->show();

这里的item->setZValue(1);是来设置图形项的深度信息的,深度大的在上面,会把下面的盖住。当然由于我们自定义的项有点小,所以盖不住整个图。我们注释掉了这句话而是用 item->setParentItem(rectItem); ,作为子类,也会显示在父类上面,即先画父类,再在父类上画子类。注意这个时候的 item->setPos(10, 10); 是针对父类的偏移,也就是针对rectItem的偏移。

为了知道所谓的坐标值,我们修改一下MyGraphicsView里面的函数,加个:

void mousePressEvent(QMouseEvent *event);

然后定义实体:

  1. void MyGraphicsView::mousePressEvent(QMouseEvent * event)
  2. {
  3. // 分别获取鼠标点击处在视图、场景和图形项中的坐标,并输出
  4. QPoint viewPos = event->pos();
  5. DebugText::getDebugText()->addContents("viewPos: " +
  6. QString::number(viewPos.x())+" "+QString::number(viewPos.y()));// "viewPos: " << viewPos;
  7. QPointF scenePos = mapToScene(viewPos);
  8. DebugText::getDebugText()->addContents("scenePos: " +
  9. QString::number(scenePos.x()) + " " + QString::number(scenePos.y()));// "viewPos: " << viewPos;
  10. QGraphicsItem *item = scene()->itemAt(scenePos, QTransform());
  11. if (item) {
  12. QPointF itemPos = item->mapFromScene(scenePos);
  13. DebugText::getDebugText()->addContents("itemPos: " +
  14. QString::number(itemPos.x()) + " " + QString::number(itemPos.y()));// "viewPos: " << viewPos;
  15. }
  16. }

这个程序的意义就是,我们点击了view区域以后,会先把视口坐标(实际物理坐标)打印出来,然后再把相应的物理坐标通过mapToScene转换到场景坐标,然后再打印场景坐标。之后判断点击的区域有没有图形项,如果有,就把图形项的坐标打印出来。

显示效果如下:我们分别点一下场景的原点,然后点一下绿色的大图形项左上角,再点一下小图形项的左上角:

注意因为屏幕分辨率实在是太高,我实在定位不到准确的右上角点,所以有所偏差。大家可以看到,首先第一个点很巧地点在了场景(0,0)位置,也就是背景图片的交点。这个交点在view视点的(109,59)的位置,这是因为默认把属于scene的图形项显示在窗口中间的缘故。点矩形,没有正好点在场景(40,40)的地方,横纵坐标都偏移了两格。然后第三次,我们点最里面的小图形项,注意这里的(6,6),是因为之前定义的图形项中我们是在(5,5)——(15,15)之间的区间画的,所以橘色区域的左上角在自己item的坐标是(5,5),(怕你们理解错再提一句,我也是实在难以正好点在(5,5)的位置上呀。。。)

现在我们把图形转一下:代码添加在本节第一个代码中。

rectItem->setRotation(30);

再在最后一行之前加一句:

scene->setSceneRect(0, 0, width(), height());

然后看效果:

首先是场景的原点变到了视图(实际物理显示区)的原点,这就是setSceneRect函数的作用,它把场景映射到物理区域的某一块地方。然后可以看到两个图形项都旋转了,这是因为我们调用父图形项,里面的子类也会一起旋转。

大家点一下各个区域,可以看到虽然旋转了,但是ItemPos自己的坐标点相对于旋转前并没有发生变动。

关于坐标系,这一节和上一节已经讲完了(我怎么可能告诉各位我是故意把一节的内容凑两节来讲呢),下一节会讲一下如何进行交互,以及限定图元的运动区域,如何在希望下一节能用一节讲完,这样我们就可以把和之前的xml文件解析的内容结合起来,开发一个传输函数控件系统了。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/91701
推荐阅读