赞
踩
再贴一段代码:注意先把上面的代码屏蔽掉:
- //坐标系实验
- QGraphicsScene *scene = new QGraphicsScene;
- MyGraphicsItem *item = new MyGraphicsItem;
- scene->addItem(item);
- //这个偏移是根据父类的偏移,而不是子类的,
- //如果不加后面的 item->setParentItem(rectItem); 父类就是场景scene了,就是根据scene的顶点偏移的。
- item->setPos(10, 10);
- //item->setZValue(1);
- QGraphicsRectItem *rectItem = scene->addRect(QRect(0, 0, 100, 100),
- QPen(Qt::blue), QBrush(Qt::green));
- item->setParentItem(rectItem);
- rectItem->setPos(40, 40);
- MyGraphicsView *view = new MyGraphicsView;
- view->setScene(scene);
- view->setForegroundBrush(QColor(255, 255, 0, 100));
- view->setBackgroundBrush(QPixmap("./ShowDebug/2.png"));
- view->resize(400, 300);
- view->show();
这里的item->setZValue(1);是来设置图形项的深度信息的,深度大的在上面,会把下面的盖住。当然由于我们自定义的项有点小,所以盖不住整个图。我们注释掉了这句话而是用 item->setParentItem(rectItem); ,作为子类,也会显示在父类上面,即先画父类,再在父类上画子类。注意这个时候的 item->setPos(10, 10); 是针对父类的偏移,也就是针对rectItem的偏移。
为了知道所谓的坐标值,我们修改一下MyGraphicsView里面的函数,加个:
void mousePressEvent(QMouseEvent *event);
然后定义实体:
- void MyGraphicsView::mousePressEvent(QMouseEvent * event)
- {
- // 分别获取鼠标点击处在视图、场景和图形项中的坐标,并输出
- QPoint viewPos = event->pos();
- DebugText::getDebugText()->addContents("viewPos: " +
- QString::number(viewPos.x())+" "+QString::number(viewPos.y()));// "viewPos: " << viewPos;
- QPointF scenePos = mapToScene(viewPos);
- DebugText::getDebugText()->addContents("scenePos: " +
- QString::number(scenePos.x()) + " " + QString::number(scenePos.y()));// "viewPos: " << viewPos;
- QGraphicsItem *item = scene()->itemAt(scenePos, QTransform());
- if (item) {
- QPointF itemPos = item->mapFromScene(scenePos);
- DebugText::getDebugText()->addContents("itemPos: " +
- QString::number(itemPos.x()) + " " + QString::number(itemPos.y()));// "viewPos: " << viewPos;
- }
- }
这个程序的意义就是,我们点击了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文件解析的内容结合起来,开发一个传输函数控件系统了。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。