QGraphicsScene 类(翻译)

场景类提供了一个管理大量的2D图元(graphical items)的平面.


场景作为QGraphicsItem的容器. 它和视图(QGraphicsView)一起使用可视化图元在2D的平面上,这些图元例如:线、矩形、文本、甚至是用户自定义的图元. 场景是图形视图框架(Graphics View Framework)的一部分.



场景还提供了功能,可以让你有效地确定item的两个位置,并确定在场景的任意区域哪些物品是可见的.使用视图,可以可视化

整个场景,也可以放大显示场景的部分.


例子:

QGraphicsScene scene;

scene.addText("Hello,world!");


QGraphicsView view(&scene);

view.show();


注意,场景本身并不可见.它只管理item。你需要创建一个视图可视化场景.


要添加item到场景中,首先要构造一个场景对象. 然后你有两个选择: 第一种你可以添加现有的QGraphicsItem对象

(通过调用addItem()),第二种你可以方便的调用函数addEllipse()、addLine()、addPath()、addPixmap()、addPolygon()、

addRect()、还有addText(). 这些函数都会返回一个新添加的item的指针. 用这些函数添加的Item的尺寸都是相对于

Item的坐标系(也可以叫图元坐标系),Item在场景中的位置被初始化为(0,0).


使用QGraphicsView可视化场景. 当场景发生变化时(场景中的Item移动或变形)场景会发送 changed()信号.要移除一个item,

调用函数removeItem().


场景使用一个索引算法(indexing algorithm)有效的管理Item的位置. 默认使用BSP树(二进制空间分区).这种算法适用于场景中

的Item处于静止. 你可以选择禁用这些索引使用函数setItemIndexMethod().关于索引算法的更多信息,查看itemIndexMethod属性


场景的包围矩形(或者说边界矩形)使用函数setSceneRect()设置.默认情况下场景的大小是没有限制的,item可以被放置在场景的任意位置,场景的边界矩形只是用来管理item的下标.如果没有设置边界矩形,场景将会使用所有item的区域作为场景矩形,这个

区域由函数itemsBoundingRect()返回.然而itemsBoundingRect()函数是一个相对耗时的函数,因为它需要收集场景中的每一个item

的位置信息.所以当操作大型的场景时通常要设置边界矩形.


场景最强大的功能就是高效管理大量的item的位置,即使是数百万个item,items()函数可以在几毫秒获得它们的位置.items()有几个重载函数有寻找item处于特定位置的,有寻找在多边形、矩形内或与他们相交的,等等.函数返回的列表按堆栈次序排列即最顶层

的item在列表的最前面. 为了方便,itemAt()函数返回指定位置的最顶层item.


场景维护选择区域的信息,要选择item,调用函数setSelectionArea().要清除当前的选择区域,调用clearSelection().

获得选择的Item列表调用函数selecteditems().


事件处理和传播

QGraphicsScene有一个责任,就是接收QGraphicsView传下来的事件。场景发送一个事件是通过继承了QEvent的构造事件,然后使用它,例如:QApplication:sendEvent()。event()是负责调度事件,一些常用的事件也有其特定的事件来处理。比如键盘事件由KeyPressEvent()来处理;鼠标事件由mousePressEvent()来处理。


键盘事件会把事件传递给焦点的item上,你也可以通过setFocusItem()来给item设置焦点,或者可以通过item自己调用QGraphicsItem::setFocus()来设置。通过调用focusItem()来获取当前焦点的Item。和widgets一样场景也可以获取自己焦点事件。默认的场景是没有焦点事件的,它摒弃了所有的键盘事件。如果调用了setFocus(),或者一个item在场景中获得了focus事件,那么场景就会自动获取该事件。如果一个场景设置了焦点,那么调用hasFocus()将会返回true,如果有键盘事件那么将会被传递给有焦点的item。如果场景失去焦点(例如:调用了clearFocus()),如果一个item有焦点事件,那么场景将维持该焦点的信息,一旦场景重新获得焦点,它将确保最后一个获得焦点的item重新获得焦点。


场景类还有mouse-over事件。如果一个item接收hove事件((see QGraphicsItem::acceptHoverEvents())),那么当鼠标进入它的区域那么他将接收到GraphicsSceneHoverEnter事件。当鼠标继续进入它的区域那么场景类将会发送一个GraphicsSceneHoverMove事件。当鼠标离开它的区域,那么item将会接收到一个GraphicsSceneHoverLeave 事件。


所有的鼠标事件都会被传递给当前的item鼠标捕获器。如果item接收了鼠标事件那么它场景的鼠标就被捕获,它就可以接收鼠标的按下事件。他可以一直保持该鼠标事件直到它释放该事件。你可以调用mouseGrabberItem()正在捕获鼠标事件。


###########################

Member Type Documentation


enum QGraphicsScene::ItemIndexMethod

这个枚举提供的是QGraphicsScene管理场景中的item的位置信息的索引方法。

QGraphicsScene::BspTreeIndex 0 (

QGraphicsScene::NoIndex -1 没有索引(适合动态场景


//---------------

enum QGraphicsScene::SceneLayer

flags QGraphicsScene::SceneLayers

这个枚举描述了QGraphicsScene的呈现层。当QGraphicsScene绘制场景内容时,它将有秩序呈现每一个item。每一层都有一个标志,当调用invalidate()或者QGraphicsView::invalidateScene(),他们将会被一起设置。


QGraphicsScene::ItemLayer 0x1

QGraphicsScene::BackgroundLayer 0x2

QGraphicsScene::ForegroundLayer 0x4

QGraphicsScene::AllLayers 0xffffff


这些SceneLayers 类型被定义在QFlags<SceneLayer>


####################################

属性文档(Property Documentation)


//-------------------------------

Access functions:

QBrush backgroundBrush () const

void setBackgroundBrush ( const QBrush & brush )


backgroundBrush : QBrush

这个背景保存场景的背景刷


设置场景背景为不同的颜色、梯度、纹理。默认的背景刷为Qt::NoBrush。背景在items前绘制。

例子:

QGraphicsScene scene;

QGraphicsView view(&scene);

view.show();


// a blue background

scene.setBackgroundBrush(Qt::blue);


// a gradient background(梯度背景)

QRadialGradient gradient(0, 0, 10);

gradient.setSpread(QGradient::RepeatSpread);

scene.setBackgroundBrush(gradient);


QGraphicsScene::render()调用 drawBackground()绘制场景的背景,怎样绘制背景更多的详细信息,你可以重写QGraphicsScene的子类drawBackground()。


//------------------------------

Access functions:


int bspTreeDepth () const

void setBspTreeDepth ( int depth )


bspTreeDepth : int

这个属性保存QGraphicsScene的BSP索引树的深度。

当使用NoIndex属性时没有影响。

这个值决定了BSP索引树的深度。深度直接影响QGraphicsScene的性能和内存使用;内存的使用跟树的深度呈指数型增长。一个最佳树深可以立即确定QGraphicsScene中item的位置,

即使场景中有数以千计甚至数以百万计的items。这也极大的提高了渲染能力。


默认该值为0,在这种情况下,Qt会根据大小、位置和数量的items场景,设置一个合理的缺省深度。如果这些参数经常变化,那么QGraphicsScene会重新调整它的内部深度,导致一些性能

会减速(变慢)。你可以通过设置该属性,来避免潜在的减速。


树的深度和场景矩形的大小决定场景粒度的划分。每个场景片段的大小取决于以下算法:


QSizeF segmentSize = sceneRect().size() / pow(2, depth - 1);


BSP树每个部分包含0 - 10个item的时候是最优规模。


//----------------------------------

Access functions:


QFont font () const

void setFont ( const QFont & font )


font : QFont

这个属性保存现场的默认字体。

这个属性提供了场景的字体。包括默认字体,和所有在场景里面的item.通过QApplication::font设置。

如果现场的字体变化,直接通过setFont()或间接使应用程序的字体变化,那么QGraphicsScene会发送一个FontChange事件,然后将FontChange事件发送给所有场景中最顶级的item。

这些items会改变自己的字体,然后通知他们的孩子,然后孩子在通知孩子,直到所有的items更新它们的字体。


改变字体,(直接或间接地通过QApplication:setFont()),它自动的重新绘制整个场景。


//--------------------------------------------

foregroundBrush : QBrush


Access functions:


QBrush foregroundBrush () const

void setForegroundBrush ( const QBrush & brush )


这个属性掌管场景的前景色。

改变这个属性来设置场景的前景色、梯度、纹理。

前景色在items绘制完以后在画,默认前景色是:Qt::NoBrush


例子:

QGraphicsScene scene;

QGraphicsView view(&scene);

view.show();


// a white semi-transparent foreground

scene.setForegroundBrush(QColor(255, 255, 255, 127));


// a grid foreground

scene.setForegroundBrush(QBrush(Qt::lightGray, Qt::CrossPattern));


QGraphicsScene::render() 调用 drawForeground()来绘制场景的前景色。更多关于怎样控制绘制前景色,请详看 QGraphicsScene下的drawForeground()函数。


//--------------------------------------------

itemIndexMethod : ItemIndexMethod


Access functions:


ItemIndexMethod itemIndexMethod () const

void setItemIndexMethod ( ItemIndexMethod method )


这个属性控制着item的索引方法。



原文:

Detailed Description


The QGraphicsScene class provides a surface for managing a large number of 2D graphical items.


The class serves as a container for QGraphicsItems. It is used together with QGraphicsView for visualizing graphical items, such as lines, rectangles, text, or even custom items, on a 2D surface. QGraphicsScene is part of the Graphics View Framework.


QGraphicsScene also provides functionality that lets you efficiently determine both the location of items, and for determining what items are visible within an arbitrary area on the scene. With the QGraphicsView widget, you can either visualize the whole scene, or zoom in and view only parts of the scene.


Example:


QGraphicsScene scene;

scene.addText("Hello, world!");


QGraphicsView view(&scene);

view.show();

Note that QGraphicsScene has no visual appearance of its own; it only manages the items. You need to create a QGraphicsView widget to visualize the scene.


To add items to a scene, you start off by constructing a QGraphicsScene object. Then, you have two options: either add your existing QGraphicsItem objects by calling addItem(), or you can call one of the convenience functions addEllipse(), addLine(), addPath(), addPixmap(), addPolygon(), addRect(), or addText(), which all return a pointer to the newly added item. The dimensions of the items added with these functions are relative to the item’s coordinate system, and the items position is initialized to (0, 0) in the scene.


You can then visualize the scene using QGraphicsView. When the scene changes, (e.g., when an item moves or is transformed) QGraphicsScene emits the changed() signal. To remove an item, call removeItem().


QGraphicsScene uses an indexing algorithm to manage the location of items efficiently. By default, a BSP (Binary Space Partitioning) tree is used; an algorithm suitable for large scenes where most items remain static (i.e., do not move around). You can choose to disable this index by calling setItemIndexMethod(). For more information about the available indexing algorithms, see the itemIndexMethod property.


The scene’s bounding rect is set by calling setSceneRect(). Items can be placed at any position on the scene, and the size of the scene is by default unlimited. The scene rect is used only for internal bookkeeping, maintaining the scene’s item index. If the scene rect is unset, QGraphicsScene will use the bounding area of all items, as returned by itemsBoundingRect(), as the scene rect. However, itemsBoundingRect() is a relatively time consuming function, as it operates by collecting positional information for every item on the scene. Because of this, you should always set the scene rect when operating on large scenes.


One of QGraphicsScene’s greatest strengths is its ability to efficiently determine the location of items. Even with millions of items on the scene, the items() functions can determine the location of an item within few milliseconds. There are several overloads to items(): one that finds items at a certain position, one that finds items inside or intersecting with a polygon or a rectangle, and more. The list of returned items is sorted by stacking order, with the topmost item being the first item in the list. For convenience, there is also an itemAt() function that returns the topmost item at a given position.


QGraphicsScene maintains selection information for the scene. To select items, call setSelectionArea(), and to clear the current selection, call clearSelection(). Call selectedItems() to get the list of all selected items.


Event Handling and Propagation


Another responsibility that QGraphicsScene has, is to propagate events from QGraphicsView. To send an event to a scene, you construct an event that inherits QEvent, and then send it using, for example, QApplication::sendEvent(). event() is responsible for dispatching the event to the individual items. Some common events are handled by convenience event handlers. For example, key press events are handled by keyPressEvent(), and mouse press events are handled by mousePressEvent().


Key events are delivered to the focus item. To set the focus item, you can either call setFocusItem(), passing an item that accepts focus, or the item itself can call QGraphicsItem::setFocus(). Call focusItem() to get the current focus item. For compatibility with widgets, the scene also maintains its own focus information. By default, the scene does not have focus, and all key events are discarded. If setFocus() is called, or if an item on the scene gains focus, the scene automatically gains focus. If the scene has focus, hasFocus() will return true, and key events will be forwarded to the focus item, if any. If the scene loses focus, (i.e., someone calls clearFocus()) while an item has focus, the scene will maintain its item focus information, and once the scene regains focus, it will make sure the last focus item regains focus.


For mouse-over effects, QGraphicsScene dispatches hover events. If an item accepts hover events (see QGraphicsItem::acceptHoverEvents()), it will receive a GraphicsSceneHoverEnter event when the mouse enters its area. As the mouse continues moving inside the item’s area, QGraphicsScene will send it GraphicsSceneHoverMove events. When the mouse leaves the item’s area, the item will receive a GraphicsSceneHoverLeave event.


All mouse events are delivered to the current mouse grabber item. An item becomes the scene’s mouse grabber if it accepts mouse events (see QGraphicsItem::acceptedMouseButtons()) and it receives a mouse press. It stays the mouse grabber until it receives a mouse release when no other mouse buttons are pressed. You can call mouseGrabberItem() to determine what item is currently grabbing the mouse.


演示站
上一篇:Qt如何使QTreeWidget始终保持展开?
下一篇:Qt怎么将界面保存为图片?

发表评论