Qt5开发学习之图形视图框架(九)

来源:互联网 发布:wps文字软件下载 编辑:程序博客网 时间:2024/06/05 16:46

图形视图体系结构

Graphics View框架结构主要特点:
1、系统可以利用Qt的反锯齿、OpenGL工具来改善绘图性能。
2、Graphics View支持事件传播体系结构,可以使图元在场景(scene)中的交互能力提升一倍,图元能够处理鼠标事件和键盘事件。
3、在框架中,可以通过二元空间划分树提供快速的图元查找,这样就能实时的显示包含上百万个图元的大场景

Graphics View的三元素:

1、场景类:QGraphicsScene类是一个用于放置图元的容器,本身是不可见的,必须通过与之相连的视图类来显示及与外界进行交互操作。通过QGraphicsScene::addItem()添加一个图元文件到场景中。QGraphicsScene::items()和一些重载函数可以返回各种形状的所有图元。QGraphicsScene::itemAt()返回指定点最顶层的图元。

场景类主要的功能包括:提供对它包含的图元的操作接口和传递事件、管理各个图元的状态(如选择和焦点处理)、提供无变换的绘制功能(如打印):

事件传播体系结构将场景事件发送给图元,同时也管理图元之间的事件传播。

管理各个图元的状态可以通过QGraphicsScene::setSelectionArea()函数选择图元,选择区域可以使任意形状,使用QPainterPath表示。若要的当前选择的图元列表,则可以使用QGraphicsScene::selectedItems()。设置图元的焦点可以使用QGraphicsScene::setFocus()QGraphicsScene::setFocusItem()函数,获得当前具有焦点的图元使用QGraphicsScene::focusItem()

使用QGraphicsScene::render()函数将场景内容绘制到特定的设备上。


2、视图类:QGraphicsView提供一个可视的窗口用于显示场景中的图元。在同一个场景中可以有多个视图,也可以为相同的数据集提供几种不同的视图。

QGraphicsView是可滚动的窗口部件,可以提供滚动条来浏览大的场景。如果需要使用OpenGL,可以使用QGraphicsView::setViewport()将视图设置为QGLWidget

视图接收鼠标和键盘的输入事件,并将它们翻译为场景事件(将坐标转换为场景的坐标),使用变换矩阵函数QGraphicsView::matrix()可以变换场景的坐标,实现场景的缩放和旋转。QGraphicsView::mapToScene()QGraphicsView::mapFromScene()用于与场景的坐标进行互相转换。


3、图元类:QGraphicsItem是场景中各个图元的基类,在它的基础上可以继承出各种图元类。

图元类主要的功能有:

  • 处理鼠标的各种事件;
  • 处理键盘输入事件;
  • 处理拖曳事件;
  • 分组;
  • 碰撞检测;

图元也有自己的坐标系,也提供场景和图元,还可以包含子图元。


GraphicsView的坐标系统

三个GraphicsView基本类有各自不同的坐标系,场景坐标、视图坐标和图元坐标。在绘制图形时,GraphicsView的场景坐标对应QPainter的逻辑坐标、视图坐标和设备坐标。

场景坐标是所有图元的基础坐标系统,描述了顶层的图元,没个图元都有场景坐标和相应的包容框;

视图坐标是窗口部件的坐标,单位是像素。以窗口左上角作为坐标系的原点。

图元坐标使用自己的本地坐标,这个坐标系统通常以图元中心为原点,这也是所有变换的原点。


图形视图

实例:制作动画

首先制作一个图元,通过定时器不停改变图元的显示。再将图元加载到场景中:
图元的制作:

#include <QObject>#include <QGraphicsItem>#include <QGraphicsView>#include <QGraphicsScene>#include <QPainter>class Butterfly : public QObject, public QGraphicsItem{    Q_OBJECTpublic:    explicit Butterfly(QObject *parent = 0);    // 在定时器函数timerEvent()对QGraphicsItem进行重绘,实现动画    void timerEvent(QTimerEvent *event);    // 图元限定区域范围,所有继承自QGraphicsItem的自定义图元都要实现此函数    QRectF boundingRect() const;signals:public slots:    // 重绘函数    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);private:    bool up; // 用于标志蝴蝶翅膀的位置,实现动画    QPixmap pix_up;    QPixmap pix_down;    qreal angle;};cpp:#include "Butterfly.h"#include <math.h>const static double PI = 3.1416;Butterfly::Butterfly(QObject *parent) : QObject(parent){    up = true;    pix_up.load("up.png");    pix_down.load("down.png");    startTimer(100);}void Butterfly::timerEvent(QTimerEvent *){    // 边界控制    // 限定蝴蝶的右边界    qreal edgex = scene()->sceneRect().right() + boundingRect().width() / 2;    // 限定蝴蝶上边界    qreal edgetop = scene()->sceneRect().top() + boundingRect().height() / 2;    // 限定蝴蝶下边界    qreal edgebottom = scene()->sceneRect().bottom() + boundingRect().height() / 2;    // 若超过了右边界则水平移回左边界    if (pos().x() >= edgex)    {        setPos(scene()->sceneRect().left(), pos().y());    }    // 若超过了上边界则垂直移回下边界    if (pos().y() <= edgetop)    {        setPos(pos().x(), scene()->sceneRect().bottom());    }    if (pos().y() >= edgebottom)    {        setPos(pos().x(), scene()->sceneRect().top());    }    // dx,dy完成蝴蝶随机飞行路径    angle += (qrand() % 10) / 20.0;    qreal dx = fabs(sin(angle * PI) * 10.0);    qreal dy = (qrand() % 20) - 10.0;    setPos(mapToParent(dx, dy));}QRectF Butterfly::boundingRect() const{    qreal adjust = 2;    return QRectF(-pix_up.width() / 2 - adjust, -pix_up.height() / 2 - adjust,                  pix_up.width() + adjust * 2, pix_up.height() + adjust * 2);}void Butterfly::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){    if (up)    {        painter->drawPixmap(boundingRect().topLeft(), pix_up);        up = !up;    }    else    {        painter->drawPixmap(boundingRect().topLeft(), pix_down);        up = !up;    }}

主函数中加载场景:

“`cpp

include

include “Butterfly.h”

include

// 完成了图元的设计,将它加载进场景中
int main(int argc, char *argv[])
{
QApplication a(argc, argv);

QGraphicsScene *scene = new QGraphicsScene;scene->setSceneRect(-100, -100, 400, 400);Butterfly *butterfly = new Butterfly;butterfly->setPos(-100, 0);scene->addItem(butterfly);QGraphicsView *view = new QGraphicsView;view->setScene(scene);view->resize(400, 400);view->show();return a.exec();

}

原创粉丝点击