1、简介
Graphics View是一个基于item的M-V架构的框架,“Qt Graphics View 提供了用于管理和交互大量定制的 2D 图形对象的平面以及可视化显示对象的视图 widget,并支持缩放和旋转功能。Graphics View 使用 BSP(二进制空间划分)树形可非常快速地找到对象,因此即使是包含百万个对象的大型场景,也能实时图形化显示。”
M-V架构的意思是, Graphics View提供一个model和一个view。所谓model就是我们添加的种种对象,所谓view就是我们观察这些对象的视口。同一个model可以由很多view从不同的角度进行观察。
Graphics View提供了一个QGraphicsScene作为场景,即是我们添加图形的空间,相当于整个世界;一个QGraphicsView作为视口,也就是我们观察的窗口,相当于照相机的取景框,这个取景框可以覆盖整个场景,也可以是场景的一部分;一些QGraphicsItem作为图形元件,以便scene添加,Qt内置了很多图形,比如line、polygon等,都是继承自QGraphicsItem。
2、例子学习
#ifndef _GRAPHICSVIEW_FRAMEWORK_H_
#define _GRAPHICSVIEW_FRAMEWORK_H_
#pragma once
/**QGraphicsItem*/
class MyItem:public QGraphicsItem
{
friend class MyView;
public:
MyItem();
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget /* = 0 */);
protected:
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
protected:
qreal course;
qreal speed;
short type;
short attribute;
QColor color;
};
class MyView:public QGraphicsView
{
Q_OBJECT
public:
MyView(QGraphicsScene* scene,QWidget* parent=0);
QAction* actionStrike;
public slots:
void timerEvent(QTimerEvent *);
};
class GraphicsViewFramework
{
public:
static void SimulatedWar();
};
#endif//_GRAPHICSVIEW_FRAMEWORK_H_
#include "stdafx.h"
#include <cmath>
#include "GraphicsViewFramework.h"
MyItem::MyItem():speed(qrand()%10+1),type(qrand()%3),attribute(qrand()%3),course(qrand()%360)
{
switch(attribute)
{
case 0:
color.setRgb(255,0,0);
break;
case 1:
color.setRgb(0,255,0);
break;
default:
color.setRgb(0,0,255);
break;
}
}
QRectF MyItem::boundingRect() const
{
qreal adjust = 0.5;
return QRectF(-20-adjust,-22-adjust,40+adjust,83+adjust);
}
void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
{
QPen pen(color);
pen.setWidth(2);
painter->setPen(pen);
switch(type)
{
case 0:
painter->drawEllipse(-15,-15,30,30);
break;
case 1:
painter->drawArc(-15,-15,30,30,180*16,180*16);
break;
default:
painter->drawLine(-15,0,0,-15);
painter->drawLine(0,-15,15,0);
break;
}
painter->drawLine(0,0,int(speed*5*cos(course)),int(speed*5*sin(course)));
}
void MyItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
QMenu menu;
menu.setWindowOpacity(0.8);
QAction* removeAction = menu.addAction(QObject::tr("武器发射"));
QAction* markAction = menu.addAction(QObject::tr("电子干扰"));
QAction* selectedAction = menu.exec(event->screenPos());
}
MyView::MyView(QGraphicsScene* scene,QWidget* parent):QGraphicsView(scene,parent)
{
startTimer(1000);
actionStrike = new QAction(QObject::tr("发射武器"),this);
}
void MyView::timerEvent(QTimerEvent * event)
{
QList<QGraphicsItem*> itemlist = items();
QGraphicsItem* item;
foreach(item,itemlist)
{
MyItem* target = (MyItem*)item;
target->setPos(target->mapToParent(target->speed*cos(target->course),target->speed*sin(target->course)));
}
}
void GraphicsViewFramework::SimulatedWar()
{
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
QGraphicsScene scene;
scene.setSceneRect(-400,-300,800,600);
scene.setItemIndexMethod(QGraphicsScene::NoIndex);
for (int i = 0; i < 200; i++)
{
MyItem* target = new MyItem();
target->setPos(qrand()%800-400,qrand()%600-300);
target->setVisible(true);
scene.addItem(target);
}
MyView view(&scene);
view.setRenderHint(QPainter::Antialiasing);
view.setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
view.setBackgroundBrush(QColor(0,0,0));
view.setCacheMode(QGraphicsView::CacheBackground);
view.setDragMode(QGraphicsView::ScrollHandDrag);
view.setWindowTitle(QObject::tr("海战模拟"));
view.resize(800,600);
view.show();
}
3、效果图