QGraphicsScene类提供了一个用于管理大量2D图形项的表面。
Header: | #include < QGraphicsScene > |
---|---|
qmake: | QT += widgets |
Inherits: | QObject |
Inherited By: | |
Since: | Qt 4.2 |
该类用作QGraphicsItems的容器。它与QGraphicsView一起使用,用于在2D表面上可视化图形项,如线、矩形、文本,甚至自定义项。QGraphicsScene是图形视图框架的一部分。
QGraphicsScene还提供了一些功能,可以让您有效地确定项目的位置,并确定在场景的任意区域内哪些项目是可见的。使用QGraphicsView小部件,您可以可视化整个场景,也可以放大并只查看场景的一部分。
QGraphicsScene scene;
QGraphicsTextItem *ti = scene.addText("Hello, world!");
// ti->setRotation (-10);
QGraphicsView view(&scene);
view.setWindowFlag (Qt::WindowMinMaxButtonsHint,false);
注意,QGraphicsScene没有自己的视觉外观;它只管理项目。您需要创建一个QGraphicsView小部件来可视化场景。
要向场景添加项目,首先要构造一个QGraphicsScene对象。然后,您有两个选项:通过调用addItem()添加现有的QGraphicsItem对象,或者可以调用一个方便的函数addEllipse()、addLine()、addPath()、addPixmap()、addPolygon()、addRect()或addText(),它们都返回指向新添加的项目的指针。使用这些函数添加的项目的尺寸是相对于项目的坐标系统的,项目的位置在场景中初始化为(0,0)。
然后,您可以使用QGraphicsView可视化场景。当场景改变时(例如,当一个项目移动或变换时),QGraphicsScene发出change() 信号。要删除项目,请调用removeItem() 。
QGraphicsScene使用索引算法来有效地管理项目的位置。默认情况下,使用BSP(二进制空间分区)树;一种适用于大型场景的算法,其中大多数物品保持静止(即不要四处走动)。您可以选择通过调用setItemIndexMethod() 禁用此索引。有关可用索引算法的更多信息,请参见 itemIndexMethod 属性。
通过调用setSceneRect() 设置场景的边界矩形。可以将项目放置在场景中的任何位置,默认情况下,场景的大小不受限制。场景rect仅用于内部簿记,维护场景的项目索引。如果未设置场景矩形,则QGraphicsScene将使用itemsBoundingRect() 返回的所有项目的边界区域作为场景矩形。但是,itemsBoundingRect() 是一个相对耗时的函数,因为它通过收集场景中每个项目的位置信息来进行操作。因此,在大型场景上操作时,应始终将场景设置为rect。
QGraphicsScene的最大优势之一就是其有效确定项目位置的能力。即使场景中有数百万个项目,items() 函数也可以在几毫秒内确定项目的位置。 item() 有几种重载:一种在特定位置查找项目,一种在多边形或矩形内或与多边形或矩形相交的项目中进行重载,等等。返回的项目列表按堆叠顺序排序,最高的项目是列表中的第一项目。为了方便起见,还有一个itemAt() 函数可在给定位置返回最上面的项目。
QGraphicsScene维护场景的选择信息。要选择项目,请调用setSelectionArea() ,并要清除当前选择,请调用clearSelection() 。调用selectedItems() 以获取所有选定项的列表。
QGraphicsScene的另一个职责是传播来自QGraphicsView的事件。要将事件发送到场景,您可以构造一个继承QEvent的事件,然后使用例如QCoreApplication::sendEvent() 将其发送。 event() 负责将事件调度到各个项目。一些常见事件由便利事件处理程序处理。例如,按键事件由keyPressEvent() 处理,鼠标按键事件由mousePressEvent() 处理。
关键事件将传递到焦点项目。要设置焦点项目,可以调用setFocusItem() ,传递接受焦点的项目,或者该项目本身可以调用QGraphicsItem::setFocus() 。调用focusItem() 以获取当前的焦点项目。为了与小部件兼容,场景还保留其自己的焦点信息。默认情况下,场景没有焦点,并且所有关键事件都将被丢弃。如果调用setFocus() 或场景中的某个项目获得焦点,则场景将自动获得焦点。如果场景具有焦点,则hasFocus() 将返回true,并将关键事件转发到焦点项(如果有)。如果场景失去焦点(例如,有人在某个项目具有焦点时调用clearFocus() ),则场景将保持其项目焦点信息,并且一旦场景重新获得焦点,它将确保最后一个焦点项目重新获得焦点。
对于鼠标悬停效果,QGraphicsScene调度悬停事件。如果某个项目接受悬停事件(请参见QGraphicsItem::acceptHoverEvents() ),则当鼠标进入其区域时,它将收到GraphicsSceneHoverEnter事件。随着鼠标继续在项目区域内移动,QGraphicsScene将向其发送GraphicsSceneHoverMove事件。当鼠标离开项目的区域时,该项目将收到GraphicsSceneHoverLeave事件。
所有鼠标事件都将传递到当前的鼠标采集器项目。如果一个项目接受鼠标事件(请参见QGraphicsItem::acceptedMouseButtons() )并且接受鼠标按下,则它将成为场景的鼠标捕获器。当没有其他鼠标按钮被按下时,它会一直停留在鼠标抓取器上,直到释放鼠标为止。您可以调用mouseGrabberItem() 来确定当前正在抓住鼠标的项目。
另请参见QGraphicsItem 和 QGraphicsView。
该枚举描述了QGraphicsScene提供的索引算法,用于管理有关场景中项目的位置信息。
Constant | Value | Description |
---|---|---|
QGraphicsScene::BspTreeIndex | 0 | 将应用二进制空间分区树。 通过使用二进制搜索,所有QGraphicsScene的项目定位算法的数量级都接近对数复杂度。 添加,移动和删除项目是对数的。 此方法最适合静态场景(即大多数项目不移动的场景)。 |
QGraphicsScene::NoIndex | -1 | 没有索引被应用。 物品的位置具有线性复杂性,因为会搜索场景中的所有物品。 但是,添加,移动和删除项目是在固定时间内完成的。 这种方法是动态场景的理想选择,在动态场景中,连续添加,移动或删除许多项目。 |
另请参见setItemIndexMethod() 和bspTreeDepth。
flags SceneLayers
该枚举描述了QGraphicsScene中的渲染层。 当QGraphicsScene绘制场景内容时,它将按顺序分别渲染每个图层。
每一层都代表一个标志,当调用诸如invalidate() 或QGraphicsView::invalidateScene() 之类的函数时,这些标志可以或在一起。
Constant | Value | Description |
---|---|---|
QGraphicsScene::ItemLayer | 0x1 | 项目层。 QGraphicsScene通过调用虚拟函数drawItems() 来渲染所有项目在此层中。 项目层绘制在背景层之后,但在前景层之前。 |
QGraphicsScene::BackgroundLayer | 0x2 | 背景层。 QGraphicsScene通过调用虚拟函数drawBackground() 在此层中渲染场景的背景。 首先绘制背景层。 |
QGraphicsScene::ForegroundLayer | 0x4 | 前景层。 QGraphicsScene通过调用虚拟函数drawForeground() 在此层中渲染场景的前景。 前景层绘制在所有层的最后。 |
QGraphicsScene::AllLayers | 0xffff | 所有层; 该值代表所有三层的组合。 |
另请参见invalidate() 和QGraphicsView::invalidateScene() 。
此属性保存场景的背景画笔
设置此属性可将场景的背景更改为不同的颜色,渐变或纹理。 默认的背景画笔是Qt::NoBrush。 在项目之前(之后)绘制背景。
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:
此属性保存QGraphicsScene的BSP索引树的深度
使用NoIndex时,此属性无效。
该值确定QGraphicsScene的BSP树的深度。深度直接影响QGraphicsScene的性能和内存使用情况。后者随树的深度呈指数增长。凭借最佳的树深度,QGraphicsScene可以立即确定项目的位置,甚至对于具有数千或数百万个项目的场景也是如此。这也大大提高了渲染性能。
默认情况下,该值为0,在这种情况下,Qt将根据场景中项目的大小,位置和数量猜测一个合理的默认深度。但是,如果这些参数频繁更改,则QGraphicsScene会在内部重新调整深度时,您可能会遇到速度变慢的情况。您可以通过设置此属性来固定树的深度,从而避免潜在的速度下降。
树的深度和场景矩形的大小决定了场景划分的粒度。每个场景段的大小由以下算法确定:
QSizeF segmentSize = sceneRect().size() / pow(2, depth - 1);
当每个分段包含0到10个条目时,BSP树有一个最佳的大小。
此属性在Qt 4.3中引入。
Access functions:
参见 itemIndexMethod 属性。
此属性保存项目在接收到触摸开始事件时是否获得焦点
通常的行为是仅在单击项目时转移焦点。通常,操作系统将触摸板上的轻击解释为等效于鼠标单击,从而在响应中生成综合的单击事件。但是,至少可以在macOS上配置此行为。
默认情况下,当您触摸触控板或类似设备时,QGraphicsScene也会转移焦点。如果将操作系统配置为在点击触控板时不生成合成鼠标,这是令人惊讶的。如果操作系统在敲击触控板时确实产生了合成的鼠标单击,则无需在开始触摸手势时进行焦点转移。
关闭focusOnTouch后,QGraphicsScene的行为与在macOS上所期望的一样。
默认值为true,以确保默认行为与5.12之前的Qt版本相同。设置为false可以防止触摸事件触发焦点更改。
此属性在Qt 5.12中引入。
Access functions:
该属性保存场景的默认字体
此属性提供场景的字体。 场景字体默认为QApplication::font并从中解析所有条目。
如果场景的字体发生更改(直接通过setFont() 或在应用程序字体更改时间接更改),则QGraphicsScene首先向自身发送FontChange事件,然后将FontChange事件发送给场景中的所有顶级窗口小部件项目。 这些项目通过将自己的字体解析为场景来进行响应,然后通知其子级,然后再次通知其子级,依此类推,直到所有小部件项都更新了其字体。
更改场景字体(直接或间接通过QApplication::setFont() )会自动计划整个场景的重绘。
Access functions:
另请参阅QWidget::font、QApplication::setFont()、palette 和 style()。
此属性保存场景的前景画刷
更改此属性,将场景前景设置为不同的颜色、渐变或纹理。
前景绘制在项目之后(顶部)。默认的前景笔刷是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子类中重新实现drawprospect()函数。
Access functions:
此属性保存项目索引方法
QGraphicsScene对场景应用索引算法,以加速items()和itemAt()等项目发现函数。索引对于静态场景是最有效的(例如,项目不会到处移动的场景)。对于动态场景,或者具有许多动画项的场景,索引簿记可以超过快速查找的速度。
对于一般情况,默认索引方法BspTreeIndex工作良好。如果你的场景使用了很多动画,并且你感到缓慢,你可以通过调用setItemIndexMethod(NoIndex)来禁用索引。
Access functions:
另请参见bspTreeDepth。
此属性保存项目必须绘制的最小视图转换大小
当场景被渲染时,任何被转换到目标视图的宽度或高度小于minimumRenderSize()的项目都不会被渲染。如果一个项没有被呈现,并且它剪辑了它的子项,它们也不会被呈现。设置此值可以加速在一个缩小视图中渲染许多对象的场景的渲染。缺省值为0。如果未设置,或者设置为0或负值,则所有项目都将始终呈现。
例如,如果一个场景是由多个视图渲染的,其中一个视图作为概述总是显示所有项目,设置这个属性就特别有用。在有许多项目的场景中,这样的视图将使用一个高比例因子,以便所有项目都可以显示。由于比例的关系,较小的项目对最终渲染场景的贡献是微不足道的。为了避免绘制这些项目和减少渲染场景所需的时间,你可以使用一个非负值调用setMinimumRenderSize()。
注意:由于太小而没有绘制的项目,仍然由Items()和itemAt()等方法返回,并参与碰撞检测和交互。建议将minimumRenderSize()设置为小于或等于1的值,以避免交互的大型未呈现项。
这个属性是在Qt 5.4中引入的。
Access functions:
另请参见QStyleOptionGraphicsItem::levelOfDetailFromTransform() 。
此属性保存场景的默认调色板
此属性提供场景的调色板。 场景面板默认为QApplication::palette,并从中解析所有条目。
如果场景的调色板发生更改(直接通过setPalette() 或在应用程序调色板发生更改时间接更改),则QGraphicsScene首先向自己发送一个PaletteChange事件,然后将PaletteChange事件发送给场景中的所有顶级控件。 这些项目通过将自己的调色板解析为场景来进行响应,然后它们通知其子级,然后再次通知其子级,依此类推,直到所有小部件项目都更新了其调色板。
更改场景调色板(直接或间接通过QApplication::setPalette() )会自动计划整个场景的重绘。
此属性在Qt 4.4中引入。
Access functions:
另请参阅QWidget::palette, QApplication::setPalette(), font, and style()。
这个属性保存场景矩形;场景的边界矩形
场景矩形定义场景的范围。它主要由QGraphicsView用于确定视图的默认可滚动区域,并由QGraphicsScene用于管理项目索引。
如果未设置,或者设置为空QRectF, scen笔直()将返回场景中所有项目的最大边界矩形(即,当项目被添加到场景或移动时,一个矩形增长,但从不收缩)。
Access functions:
参见width(), height()和QGraphicsView:: scen勃起。
这个属性保存了点击进入场景背景是否会清除焦点
在设置stickyFocus为true的QGraphicsScene中,当用户单击场景背景或不接受焦点的项目时,焦点将保持不变。否则焦点将被清除。默认情况下,此属性为false。
当鼠标按下时,焦点会发生变化。您可以在QGraphicsScene的子类中重新实现mousePressEvent(),以根据用户单击的位置切换该属性。
这个属性是在Qt 4.6中引入的。
Access functions:
参见clearFocus()和setFocusItem()。
bool isActive() const
如果场景处于活动状态(例如,至少一个处于活动状态的QGraphicsView对其进行查看),则返回true; 否则返回false。
QGraphicsItem * activePanel() const 返回当前活动的面板
void setActivePanel(QGraphicsItem *item) 激活item,该项目必须是此场景中的项目
QGraphicsWidget * activeWindow() const 返回当前活动窗口
void setActiveWindow(QGraphicsWidget *widget) 激活小部件,该小部件必须是此场景中的小部件。
QStyle * style() const 返回场景的样式
void setStyle(QStyle *style) 将场景的样式设置或替换为style,并将样式作为该场景的父项
virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const
输入法使用此方法来查询场景的一组属性,以便能够支持复杂的输入法操作,以支持周围的文本和重新转换。
查询参数指定要查询的属性。
void invalidate(qreal x, qreal y, qreal w, qreal h, QGraphicsScene::SceneLayers layers = AllLayers)
QGraphicsItem * mouseGrabberItem() const返 回当前的鼠标抓取器项目
如果当前没有任何项目在抓取鼠标,则返回nullptr。 鼠标采集器项目是接收发送到场景的所有鼠标事件的项目。
当一个项目接收并接受鼠标按下事件时,它便成为鼠标抓取器,并且在发生以下两个事件之一之前,它将一直保留在鼠标抓取器中:
void render(QPainter *painter, const QRectF &target = QRectF(), const QRectF &source = QRectF(), Qt::AspectRatioMode aspectRatioMode = Qt::KeepAspectRatio)
使用 painter 将 source矩形 从场景渲染到 target矩形
此功能对于将场景的内容捕获到绘图设备(例如QImage(例如,截取屏幕截图))或使用QPrinter进行打印很有用。 例如:
QGraphicsScene scene;
scene.addItem(...
...
QPrinter printer(QPrinter::HighResolution);
printer.setPaperSize(QPrinter::A4);
QPainter painter(&printer);
scene.render(&painter);
如果source是一个null rect,则此函数将使用sceneRect() 确定要渲染的内容。 如果target是一个null rect,则将使用画家的绘画设备的尺寸。
source矩形 的内容将根据AspectRatioMode进行转换以适合 target矩形 。 默认情况下,将保持宽高比,并缩放源以适合目标。
void update(qreal x, qreal y, qreal w, qreal h)
QList
bool sendEvent(QGraphicsItem *item, QEvent *event) 通过可能的事件过滤器将事件事件发送到项目项
仅在启用该项目的情况下才发送事件。
如果事件已被过滤或该项目被禁用,则返回false。 否则,返回事件处理程序返回的值。
QGraphicsEllipseItem * addEllipse(const QRectF &rect, const QPen &pen = QPen(), const QBrush &brush = QBrush())
QGraphicsEllipseItem * addEllipse(qreal x, qreal y, qreal w, qreal h, const QPen &pen = QPen(), const QBrush &brush = QBrush())
创建一个椭圆项目并将其添加到场景中,并返回项目指针
QGraphicsLineItem * addLine(const QLineF &line, const QPen &pen = QPen())
QGraphicsLineItem * addLine(qreal x1, qreal y1, qreal x2, qreal y2, const QPen &pen = QPen())
创建一个线条项并将其添加到场景中,并返回项目指针
QGraphicsRectItem * addRect(const QRectF &rect, const QPen &pen = QPen(), const QBrush &brush = QBrush())
QGraphicsRectItem * addRect(qreal x, qreal y, qreal w, qreal h, const QPen &pen = QPen(), const QBrush &brush = QBrush())
创建一个矩形项目并将其添加到场景中,并返回项目指针
QGraphicsPolygonItem * addPolygon(const QPolygonF &polygon, const QPen &pen = QPen(), const QBrush &brush = QBrush())
创建一个多边形项目并将其添加到场景中,并返回项目指针
QGraphicsPathItem * addPath(const QPainterPath &path, const QPen &pen = QPen(), const QBrush &brush = QBrush())
创建路径项并将其添加到场景,然后返回项指针
QGraphicsPixmapItem * addPixmap(const QPixmap &pixmap)
创建一个pixmap项目并将其添加到场景,并返回项目指针
QGraphicsTextItem * addText(const QString &text, const QFont &font = QFont())
创建一个文本项并将其添加到场景中,并返回该项的指针
QGraphicsSimpleTextItem * addSimpleText(const QString &text, const QFont &font = QFont())
创建一个QGraphicsSimpleTextItem并将其添加到场景,并返回项目指针
void addItem(QGraphicsItem *item)
void removeItem(QGraphicsItem *item)
QGraphicsProxyWidget * addWidget(QWidget *widget, Qt::WindowFlags wFlags = Qt::WindowFlags())
QGraphicsItem * itemAt(const QPointF &position, const QTransform &deviceTransform) const
QGraphicsItem * itemAt(qreal x, qreal y, const QTransform &deviceTransform) const
QList
QList
QList
QList
QList
QList
QList
QGraphicsItemGroup * createItemGroup(const QList
void destroyItemGroup(QGraphicsItemGroup *group)
enum Qt::ItemSelectionMode
此枚举由QGraphicsItem,QGraphicsScene 和 QGraphicsView 来使用来指定如何选择项目,或如何确定形状和项目是否碰撞。
Constant Value Description Qt::ContainsItemShape 0x0 输出列表仅包含形状完全包含在选择区域内的项目。 与区域轮廓相交的项目不包括在内。 Qt::IntersectsItemShape 0x1 输出列表包含形状完全包含在选择区域内的项目以及与该区域的轮廓相交的项目。 这是橡皮筋选择的常见模式。 Qt::ContainsItemBoundingRect 0x2 输出列表仅包含其边界矩形完全包含在选择区域内的项目。 与区域轮廓相交的项目不包括在内。 Qt::IntersectsItemBoundingRect 0x3 输出列表既包含边界矩形完全包含在选择区域内的项目,又包含与该区域的轮廓相交的项目。 此方法通常用于确定需要重绘的区域。 另请参见QGraphicsScene::items() ,QGraphicsScene::collidingItems() ,QGraphicsView::items() ,QGraphicsItem::collidesWithItem() 和 QGraphicsItem::collidesWithPath() 。
enum Qt::FocusReason
该枚举指定了焦点更改的原因。 它将通过QWidget::setFocus传递,并且可以在焦点更改时在发送到小部件的QFocusEvent中进行检索。
Constant Value Description Qt::MouseFocusReason 0 发生鼠标动作。 Qt::TabFocusReason 1 按下Tab键。 Qt::BacktabFocusReason 2 发生了Backtab。 为此的输入可能包括Shift或Control键。 例如 Shift + Tab。 Qt::ActiveWindowFocusReason 3 窗口系统使该窗口处于活动状态或非活动状态。 Qt::PopupFocusReason 4 该应用程序打开/关闭一个弹出窗口,该弹出窗口抓住/释放了键盘焦点。 Qt::ShortcutFocusReason 5 用户键入了标签的好友快捷方式 Qt::MenuBarFocusReason 6 菜单栏成为焦点。 Qt::OtherFocusReason 7 另一个原因,通常是特定于应用程序的。 另请参阅小部件中的键盘焦点。
void advance()
通过为场景中的所有项目调用QGraphicsItem::advance() ,此插槽使场景前进一步。 这分两个阶段完成:在第一阶段,所有项目都被通知场景将要更改,在第二阶段中,所有项目都被通知它们可以移动。 在第一阶段,调用QGraphicsItem::advance() 传递值0作为参数,在第二阶段传递1。
请注意,您也可以将“动画框架”用于动画。
void clear()
从场景中删除所有项目,但在其他情况下,场景的状态保持不变。
另请参见addItem() 。
void clearSelection() 清除当前选择。
另请参见setSelectionArea() 和selectedItems() 。
void invalidate(const QRectF &rect = QRectF(), QGraphicsScene::SceneLayers layers = AllLayers)
使场景中的rect无效并计划其重绘。 图层中的所有缓存内容都将无条件无效并重新绘制
可以使用此函数重载来通知QGraphicsScene场景的背景或前景的变化。 此功能通常用于具有基于图块的背景的场景,以在QGraphicsView启用CacheBackground时通知更改。
QRectF TileScene::rectForTile(int x, int y) const
{
// Return the rectangle for the tile at position (x, y).
return QRectF(x * tileWidth, y * tileHeight, tileWidth, tileHeight);
}
void TileScene::setTile(int x, int y, const QPixmap &pixmap)
{
// Sets or replaces the tile at position (x, y) with pixmap.
if (x >= 0 && x < numTilesH && y >= 0 && y < numTilesV) {
tiles[y][x] = pixmap;
invalidate(rectForTile(x, y), BackgroundLayer);
}
}
void TileScene::drawBackground(QPainter *painter, const QRectF &exposed)
{
// Draws all tiles that intersect the exposed area.
for (int y = 0; y < numTilesV; ++y) {
for (int x = 0; x < numTilesH; ++x) {
QRectF rect = rectForTile(x, y);
if (exposed.intersects(rect))
painter->drawPixmap(rect.topLeft(), tiles[y][x]);
}
}
}
请注意,QGraphicsView当前仅支持后台缓存(请参阅QGraphicsView::CacheBackground)。 如果传递了除BackgroundLayer以外的任何层,则此函数等效于调用update() 。
另请参见QGraphicsView::resetCachedContent() 。
void update(const QRectF &rect = QRectF())
计划重新绘制场景中的rect。
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setApplicationName ("QGraphicsScene");
// QGraphicsScene scene;
QGraphicsScene scene(-200,-200,400,400);
scene.setBackgroundBrush (Qt::white);
QPen pen;
pen.setColor (Qt::red);
scene.addLine (0,0,0,50,pen);
scene.addLine (0,0,50,0,pen);
scene.addLine (0,0,50,50,pen);
scene.addText ("Hello World 2");
pen.setColor (Qt::green);
scene.addRect (-100,-100,200,200,pen);
QGraphicsView view(&scene);
// view.setRenderHints (QPainter::Antialiasing);
view.setWindowFlag (Qt::WindowMinMaxButtonsHint,false);
view.setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOn);
view.setVerticalScrollBarPolicy (Qt::ScrollBarAlwaysOn);
qDebug() << scene.itemsBoundingRect ();
qDebug() << scene.sceneRect ();
view.show();
return a.exec();
}