# QGraphicsScene QGraphicsView QGraphicsItem

Graphics View提供了一个界面，它既可以管理大数量的定制2D graphical items，又可与它们交互，有一个view widget可以把这些项绘制出来，并支持旋转与缩放。这个柜架也包含一个事件传播结构，对于在scene中的这些items,它具有双精度的交互能力。Items能处理键盘事件，鼠标的按，移动、释放、双击事件，也可以跟踪鼠标移动。Graphics View使用BSP树来提供对item的快速查找，使用这种技术，它可以实时地绘制大规模场景，甚至以百万items计。Graphics View在Qt 4.2中被引用，它替代了它的前辈QCanvas。

# Graphics View的体系结构

Graphics View提供的是一种类似于Qt model-view的编程。多个views可以监视同一个场景，而场景包含多个具有多种几何外形的items。

## 场景

QGraphicsScene 表示Graphics View中的场景，它有以下职责：

QGraphicsScene  scene;
QGraphicsItem  *item=scene.itemAt(50,50);
//item==rect;
QGraphicsScene的事件传播结构会把场景事件投递到items，也管理多个items之间的传递。假如场景收到了鼠标在某个位置press事件，场景会把这个事件投递给处在那个位置的item。QGraphicsScene也管理某种item状态，像选择与焦点。你可以通过调用QGraphicsScene::setSelectionArea()来选择items，它需要提供一个任意的形状为参数。这个函数也作为在QGraphicsView实现橡皮筋选择功能的一个基础。为得到这些已经被选择的items,调用QGraphicsScene::selectedItem()。另一个状态处理是是否一个item拥有键盘输入焦点。你可以调用QGraphicsScene::setFocusItem()或QGraphics::setFocus()来设定焦点，也可用QGraphicsScene::focusItem()来得到当前拥有焦点的那个item。最后，QGraphicsScene允许你通过调用QGraphicsScene::render()函数把部分场景送到绘图设备进行渲染。

## 视图

QGraphicsView提供了视图部件，它可视化场景中的内容。你可以联结多个视图到同一个场景，对这个相同的数据集提供几个视口。视口部件是一个滚动区域，它提供了滚动条以对大场景进行浏览。为了使用OpenGL,你应该调用QGraphicsView::setViewport()来把一个QGLWidget设为视口。视图从键盘，鼠标接收输入事件，在发送这些事件到场景之前，会对这些事件进行适当的翻译（把事件坐标转换成对应的场景坐标）。

The Item
QGraphicsItem 是场景中图形items的基类。Graphics View 提供了一些标准的、用于典型形状的items。像矩形(QGraphicsRectItem),椭圆（QGraphicsEllipseItem),文本(QGraphicsTextItem),当你写定制的item时，那些最有用的一些QGraphicsItem特性也是有效的。除此这外，QGraphicsItem支持以下特性：
*鼠标按、移动、释放、双击事件，鼠标悬停事件，滚轮事件，弹出菜单事件。
*键盘输入焦点，键盘事件。
*拖拽
*组，包括父子关系，使用QGraphicsItemGroup
*碰撞检测
Items如同QGraphicsView一样，位于本地坐标系，它也为item与场景之间，item与item之间的坐标转换提供许多工具函数。而且，也像QGraphicsView一样，它使用矩阵来变换它的坐标系统：QGraphicsItem::matrix()。它对旋转与缩放单个的Item比较有用。
Items可以包含别的items(孩子）。父items的转换被它的子孙所继承。然而，它的所有函数（也就是，QGraphicsItem::contains(),QGraphicsItem::boundingRect(),QGraphicsItem::collidesWith()),不会积累这些转换，依然在本地坐标下工作。
QGraphicsItem通过QGraphicsItem::shape()，QGraphicsItem::collideWith())来支持碰撞检测。这两个都是虚函数。从shape()返回你的item的形状（以本地坐标QPainterPath表示），QGraphicsItem会为你处理所有的碰撞检测。假如你想提供自己的碰撞检测，你应该重新实现QGraphicsItem::collideWith()。

## Graphics View 坐标系统

Graphics View基于笛卡尔坐标系。item在场景中的位置与几何形状通过x,y坐标表示。当使用未经变形的视图来观察场景时，场景中的一个单位等于屏幕上的一个像素。在Graphics View中有三个有效的坐标系统：Item坐标系，场景坐标系，视图坐标系。为了简化你的实现，Graphics View提供了方便的函数，允许三个坐标系之间相互映射。

## Item坐标

Items位于它们自己的坐标系中。它的坐标都以点(0,0)为中心点，这也是所有变换的中心点。在item坐标系中的几何图元，经常被称为item点，item线，item矩形。当创建一个定制的item,item坐标是所需要考虑的。QGraphicsScene与QGraphicsView可以为你执行所有转换，这使得实现定制的item变得容易。举例来说，假如你收到鼠标按或是拖进入事件，事件的位置以item坐标的形式给出。QGraphicsItem::contain()虚函数，当某个点的位置在你的item范围内时，返回true,否则返回false。这个点参数使用item坐标，相似地，item的包围矩形与形状也使用item坐标。
Item位置指的是item的中心点在它父亲的坐标系中的坐标。以这种思想来看，场景指的就是那些祖先最少的item的“父亲”。最上级的Item位置就是在场景中的位置。

## 关键特性

### 缩放与旋转

QGraphicsView通过QGraphicsView::setMatrix()支持同QPainter一样的仿射变换，通过对一个视图应用变换，你可以很容易地支持普通的导航特性如缩放与旋转。下面是一个例子：
class View:;public QGraphicsView
{
Q_OBJECT
//…..
public slots:
void zoomIn() {scale(1.2,1.2);}
void zoomOut() {scale(1/1.2,1/1.2);}
void rotateLeft() {rotate(-10);}
void rotateRight() {rotate(10);}
};

### 拖拽

void CustomItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
QMimeData *data=new QMimeData;
data->setColor(Qt::green);
QDrag *drag=new QDrag(event->widget());
drag->setMimeData(data);
drag->start();
}

## 光标与工具提示

### 动画

Graphics View支持几种级别的动画。你可以很容易地通过把QGraphicsItemAnimatoin与你的item联结来

### OpenGL渲染

QGraphicsView view(&scene);
view.setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));

### Item组

QGraphicsItemGroup仍会保留item的原始位置与变换，而给一个item重新指定父item则会让item根据其新的父亲重新定位。可以用QGraphicsScene::createItemGroup()建组。

//myitem.cpp
//myitem.h
#ifndef MYITEM_H
#define MYITEM_H

#include <QGraphicsItem>

class MyItem : public QGraphicsItem
{
public:
MyItem();
QRectF boundingRect() const;
void paint(QPainter *painter,const QStyleOptionGraphicsItem *option,QWidget *widget);
};

#endif // MYITEM_H
//myitem.cpp
#include "myitem.h"
#include
MyItem::MyItem()
{
}

QRectF MyItem::boundingRect() const
{
}

void MyItem::paint(QPainter *painter,const QStyleOptionGraphicsItem *option,QWidget *widget)
{
painter->drawRect(0,0,200,200);

}
//main.cpp
#include <QtGui/QApplication>
#include
#include
#include
#include
#include"myitem.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);

QGraphicsScene scene;
scene.setSceneRect(-300,-300,600,600);
scene.setItemIndexMethod(QGraphicsScene::NoIndex);

MyItem *item=new MyItem;

QGraphicsView view(&scene);
view.setRenderHint(QPainter::Antialiasing);
view.setCacheMode(QGraphicsView::CacheBackground);
view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
view.setDragMode(QGraphicsView::ScrollHandDrag);
view.resize(400,300);
view.show();
return a.exec();
}

### 15 replies ›

1. I and also my guys were actually digesting the great advice from your web page and then instantly I got a terrible suspicion I never thanked the web blog owner for those strategies. My guys ended up certainly very interested to study them and have in effect in actuality been loving these things. Appreciation for indeed being considerably accommodating and also for utilizing such fabulous things most people are really desirous to discover. My honest apologies for not saying thanks to you earlier.

2. I and also my friends appeared to be looking through the good tips from your website and then then I got a horrible feeling I had not expressed respect to the web site owner for those secrets. The young boys are actually as a consequence excited to read through all of them and have now clearly been taking pleasure in them. Appreciate your really being well helpful as well as for deciding upon such fantastic information millions of individuals are really desirous to be aware of. My very own sincere apologies for not expressing gratitude to you earlier.

3. I together with my friends have been digesting the excellent advice from your web site then at once I got an awful feeling I never expressed respect to the site owner for those strategies. All the men were definitely certainly thrilled to read all of them and already have pretty much been using them. Thank you for getting really kind and also for settling on variety of good ideas most people are really desirous to discover. My very own sincere regret for not saying thanks to sooner.

4. I’m commenting to let you understand what a brilliant experience our child went through going through your web site. She came to find such a lot of issues, which include what it is like to possess an excellent coaching nature to get the rest very easily understand specified extremely tough matters. You actually did more than visitors’ expectations. I appreciate you for distributing the great, dependable, informative and as well as fun thoughts on your topic to Evelyn.

5. I intended to put you that little bit of note just to give thanks as before relating to the pleasing advice you have discussed here. It was simply seriously generous with you to give unhampered all that most people could have advertised for an e book to help with making some profit for their own end, particularly considering the fact that you could possibly have tried it in case you decided. These tips also acted to become a fantastic way to understand that other people online have the identical dreams really like my very own to understand very much more with respect to this matter. I’m sure there are millions of more fun occasions in the future for many who view your blog post.

6. I just wanted to send a quick word to be able to say thanks to you for all the wonderful recommendations you are giving out on this website. My rather long internet lookup has at the end of the day been recognized with pleasant insight to write about with my guests. I ‘d believe that most of us site visitors are really fortunate to be in a really good network with so many wonderful professionals with great tips. I feel really lucky to have come across your web site and look forward to really more pleasurable moments reading here. Thanks a lot once more for everything.

7. I’m just writing to let you be aware of what a wonderful discovery my wife’s girl encountered reading your blog. She even learned a wide variety of issues, not to mention what it is like to have an awesome helping mindset to have the mediocre ones easily know precisely chosen complex topics. You truly did more than people’s expectations. Thanks for coming up with these useful, healthy, informative as well as fun guidance on that topic to Gloria.

8. I in addition to my friends have been looking at the nice tactics found on your website and all of a sudden I got a terrible feeling I had not expressed respect to the web blog owner for those secrets. These people had been as a result glad to learn all of them and already have clearly been tapping into them. I appreciate you for turning out to be simply kind and then for going for this form of incredibly good topics most people are really needing to be aware of. Our honest apologies for not saying thanks to sooner.

9. I am just commenting to make you know of the magnificent encounter my friend’s daughter undergone reading your blog. She discovered a good number of details, not to mention how it is like to have a great giving mood to have other people smoothly completely grasp specified problematic matters. You truly surpassed our own expected results. I appreciate you for supplying the great, trusted, informative and as well as cool tips on that topic to Ethel.

10. I wish to show my admiration for your kindness giving support to folks that require assistance with this particular area of interest. Your personal dedication to getting the message all over was amazingly beneficial and has constantly permitted folks like me to achieve their objectives. Your valuable suggestions means a whole lot a person like me and even further to my colleagues. Thanks a ton; from all of us.

11. I want to point out my appreciation for your generosity supporting all those that need help on this one issue. Your very own dedication to passing the message all-around became exceptionally important and has in most cases enabled guys like me to reach their dreams. Your new helpful guidelines implies a lot a person like me and far more to my peers. Many thanks; from each one of us.

12. Thanks so much for giving everyone an extraordinarily wonderful opportunity to check tips from this site. It is usually so kind plus packed with fun for me and my office colleagues to visit your blog the equivalent of thrice per week to learn the latest tips you have. And of course, I am at all times fulfilled considering the remarkable suggestions you serve. Certain 2 points in this post are indeed the best I’ve ever had.

13. I simply wanted to send a quick remark so as to thank you for some of the fabulous ideas you are sharing on this site. My extended internet look up has finally been recognized with extremely good details to write about with my partners. I ‘d repeat that many of us website visitors are unequivocally lucky to exist in a useful place with so many lovely people with interesting plans. I feel somewhat blessed to have encountered your web page and look forward to so many more fabulous times reading here. Thanks a lot once more for everything.

14. I precisely desired to say thanks yet again. I’m not certain the things I might have carried out in the absence of these thoughts shared by you about that area of interest. It had been a very frightening dilemma in my view, nevertheless observing a new well-written technique you treated it made me to cry with joy. Now i’m thankful for your support as well as sincerely hope you find out what a great job you are always doing teaching people by way of a site. Probably you’ve never encountered all of us.