Qt图形视图、动画、状态机框架

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Graphics View的坐标系统
3.图形项坐标
QGraphicsItem类的坐标系,若在调用QGraphicsItem类的paint()函数重绘图元 时,则以此坐标系为基准。它的坐标都以点(0,0)为中心点,这也是所有变换的中 心点。 图形项位置指的是图形项的中心点在它父亲的坐标系中的坐标。如无父亲图 形项,则选场景坐标系。以这种思想来看,场景指的就是那些祖先最少的图形项 的“父亲”。最上级的图形项位置就是在场景中的位置。 子图形项会随着父图形项的变换而变换。(一起缩放,一起旋转等)。
可自定义新的图形项 注:Item的绘制是基于它本身的局部坐标系的。
支持如下功能: 鼠标按下、移动、释放、双击、悬停、滚轮、右键菜单 键盘输入焦点和键盘事件 拖放事件 父子图形项 分组,通过QGraphicsItemGroup 支持自定义数据,setData(), data()
自定义图形项
class MyItem : public QGraphicsItem { public: MyItem(); QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); }; QRectF MyItem::boundingRect() const { qreal penWidth = 1; return QRectF(0-penWidth/2., 0-penWidth/2., 20+penWidth, 20 + penWidth); } void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { painter->setBrush(Qt::red); painter->drawRect(0,0,20,20); }
Qt图形视图框架、动画框架、 状态机框架
Baidu Nhomakorabea
思考
• 动画、交互(控制)是由事件来驱动的(比如常见的定时 器事件、键盘事件等)
– 模拟时钟的动画
• 思考一下,若要以交互、动画地方式展现一个大的场景, 里边部件(准确来说应为图形项)很多,会遇到什么问题?
图形视图框架
Graphics View框架的特点
(1)Graphics View框架结构中,系统可以利用Qt绘图系统的反锯齿、 OpenGL工具来改善绘图性能。 (2)Graphics View框架支持事件传播,图形项在场景(scene)中可以交互, 图形项能够处理键盘事件和鼠标事件等。其中,鼠标事件包括鼠标按下、移动、 释放和双击,还可以跟踪鼠标的移动。 (3)在Graphics View框架中,通过二叉空间分割(Binary Space Partitioning, BSP)树提供快速的图形项查找,这样就能够实时地显示包含上百万个图形项的 大场景。BSP也用于碰撞检测。
QGraphicsScene 表示Graphics View中的场景,它有以下职责:
• 为管理大量的图形项提供一个快速的接口。 • 传播事件到每个图形项。 • 管理图形项的状态,例如选择,焦点处理。 • setSelectionArea(), selectedItems(), setFocusItem()等 • 提供未经变换的渲染功能,主要用于打印。 • render() • 场景作为QGraphicsItem对象的容器。通过调用 QgraphicsScene::addItem()把图形项加入到场景中。 • 可以使用众多的查找函数来获取特定的图形项。 • items(), itemAt()
view.setForegroundBrush(QColor(255,255,255,100)); view.setBackgroundBrush(QPixmap(":/Desert.jpg")); view.resize(400,300); view.show();
return app.exec(); }
QGraphicsItem(图形项)
QGraphicsItem 是场景中图形items的基类。Graphics View 提供了一 些标准的、用于典型形状的items。 矩形(QGraphicsRectItem) 椭圆(QGraphicsEllipseItem) 文本(QGraphicsTextItem)等
小结
QGraphicsScene相当于画布,把众多的QGraphicsItem整合在一起。 而QGraphView则是QGraphicsScene显示层,即QGraphicsScene完成了 “概念上”的显示元素的设计,而QGraphicsView则是一种窗口元素,它 完成了显示元素的显示,相当于照相机的取景框,这个取景框可以覆盖 整个场景,也可以是场景的一部分。
int main(int argc, char * argv[]) { QApplication app(argc, argv); QGraphicsScene scene; QGraphicsRectItem * item = new QGraphicsRectItem(0,0,100,100); scene.addItem(item); QTransform transform; qDebug() << scene.itemAt(50.,50., transform); QGraphicsView view(&scene);
图形效果
QGraphicsEffect 是所有图形效果的基类。通过在源对象(如一个图形项)和目标 设备(如视图的视口)之间过节了渲染管道和一些操作来实现图形效果,Qt提供 了如下4个标准的图形效果: 模糊效果 QGraphicsBlurEffect 染色效果 QGraphicsColorizeEffect 阴影效果 QGraphicsDropShadowEffect 透明效果 QGraphicsOpacityEffect 使用方法: 先创建一个图形效果对象,再调用setGraphicsEffect()即可。 QGraphicsBlurEffect * blurEffect = new QGraphicsBlurEffect; blurEffect->setBlurHints(QGraphicsBlurEffect::QualityHint); blurEffect->setBlurRadius(8); setGraphicsEffect(blurEffect); 停止效果使用setEnabled(false) 【返回所用图形效果:QGraphicsEffect * QGraphicsItem::graphicsEffect() const】
注意:此处的(0,0,100,100)表示图形项的坐标,不是在场景中的位置
QGraphicsView(视图)
QGraphicsView提供了视图部件,用来可视化场景中的内容。可以联 结多个视图到同一个场景,对这个相同的数据集提供几个视口。视口部 件是一个滚动区域,它提供了滚动条以对大场景进行浏览。 setDragMode(): ScrollHandDrag, RubberBandDrag setViewport(): QGLWidget可支持OpenGL渲染
Graphics View坐标系
Graphics View基于笛卡尔坐标系。item在场景中的位置与几何形状通 过(x,y)坐标表示。当使用未经变形的视图来观察场景时,场景中的一个 单位等于屏幕上的一个像素。在Graphics View中有三个有效的坐标系统: 图形项坐标系,场景坐标系,视图坐标系。为了简化实现,Graphics View提供了方便的函数,允许三个坐标系之间相互映射。
int main(int argc, char * argv[]) { QApplication app(argc, argv); QGraphicsScene scene; QGraphicsRectItem * item = new QGraphicsRectItem(0,0,100,100); scene.addItem(item); QTransform transform; qDebug() << scene.itemAt(50.,50., transform); return app.exec(); }
e
Graphics View的坐标系统
2.视图坐标
QGraphicsView类继承自QWidget类,因此它与其他的QWidget类一样,以窗口 的左上角作为自己坐标系的原点,如图所示。 视图坐标是widget的坐标,视图坐标中每个单位对应一个像素。这种坐标的 特殊之处在于它是相对于widget或是视口的,不会被所观察的场景所影响。 QGraphicsView的视口的左上角总是(0,0),右下角总是(视口宽,视口高)。 所有的鼠标事件与拖拽事件,最初以视图坐标表示,需要把这些坐标映射到场景 坐标以便与图形项交互。
7.1.2 Graphics View的三元素
Graphics View框架结构主要包含三个类,场景类(QGraphicsScene)、视图 类(QGraphicsView)和图形项类(QGraphicsItem)(又称图元类),统称为“三 元素”。 它们三者之间的关系如图所示。
QGraphicsScene(场景)
Graphics View的坐标系统
1.场景坐标
QGraphicsScene类的坐标系以中心为原点(0,0),如图所示。 场景坐标系统描述了每个最顶级图形项的位置,也是从视图向场景投递场景 事件的基础。场景中的每个图形项有场景位置与包围矩形 (QGraphicsItem ::scenePos(), QGraphicsItem::sceneBoundingRect()), 另外,它有 自己本地图形项位置与包围矩形。场景位置描述了图形项在场景坐标下的位置, 它的场景包围矩形则用于QGraphicsScene决定场景中哪块区域发生了变化。场景 中的变化通过QGraphicsScene::changed ()信号来通知,它的参数是场景矩形列表。
Graphics View的坐标系统
Graphics View框架提供了多种坐标变换函数:
自定义视图、三种坐标关系
class MyView : public QGraphicsView { public: MyView(); protected: void mousePressEvent(QMouseEvent *); }; void MyView::mousePressEvent(QMouseEvent * event) { QPoint viewPos = event->pos(); qDebug() << "viewPos: " << viewPos; QPointF scenePos = mapToScene(viewPos); qDebug() << "scenePos: " << scenePos; QGraphicsItem * item = scene() ->itemAt(scenePos, QTransform()); if ( item ) { QPointF itemPos = item -> mapFromScene(scenePos); qDebug() << "itemPos: " << itemPos; } }
使用advance()实现动画
可以使用QGraphicsScene::advance()来推进场景,定时器timeout()信号和场景的 advance()槽关联。 QTimer timer; QObject::connect(&timer, SIGNAL(timeout()), &scene, SLOT(advance())); timer.start(1000 / 33); 场景的advance()槽执行时会调用每个图形项的advance()函数(不是槽)。所以只需 要重写每个图形项的advance()函数即可。 void Mouse::advance(int step) { if (!step) return; ... }
相关文档
最新文档