📄 qgraphicsview.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************///#define QGRAPHICSVIEW_DEBUGstatic const int QGRAPHICSVIEW_REGION_RECT_THRESHOLD = 50;/*! \class QGraphicsView \brief The QGraphicsView class provides a widget for displaying the contents of a QGraphicsScene. \since 4.2 \ingroup multimedia \mainclass QGraphicsView visualizes the contents of a QGraphicsScene in a scrollable viewport. To create a scene with geometrical items, see QGraphicsScene's documentation. QGraphicsView is part of \l{The Graphics View Framework}. To visualize a scene, you start by constructing a QGraphicsView object, passing the address of the scene you want to visualize to QGraphicsView's constructor. Alternatively, you can call setScene() to set the scene at a later point. After you call show(), the view will by default scroll to the center of the scene and display any items that are visible at this point. For example: \code QGraphicsScene scene; scene.addText("Hello, world!"); QGraphicsView view(&scene); view.show(); \endcode You can explicitly scroll to any position on the scene by using the scroll bars, or by calling centerOn(). By passing a point to centerOn(), QGraphicsView will scroll its viewport to ensure that the point is centered in the view. An overload is provided for scrolling to a QGraphicsItem, in which case QGraphicsView will see to that the center of the item is centered in the view. If all you want is to ensure that a certain area is visible, (but not necessarily centered,) you can call ensureVisible() instead. QGraphicsView can be used to visualize a whole scene, or only parts of it. The visualized area is by default detected automatically when the view is displayed for the first time (by calling QGraphicsScene::itemsBoundingRect()). To set the visualized area rectangle yourself, you can call setSceneRect(). This will adjust the scroll bars' ranges appropriately. Note that although the scene supports a virtually unlimited size, the range of the scroll bars will never exceed the range of an integer (INT_MIN, INT_MAX). When the scene is larger than the scroll bars' values, you can choose to use translate() to navigate the scene instead. QGraphicsView visualizes the scene by calling render(). By default, the items are drawn onto the viewport by using a regular QPainter, and using default render hints. To change the default render hints that QGraphicsView passes to QPainter when painting items, you can call setRenderHints(). By default, QGraphicsView provides a regular QWidget for the viewport widget. You can access this widget by calling viewport(), or you can replace it by calling setViewport(). To render using OpenGL, simply call setViewport(new QGLWidget). QGraphicsView takes ownership of the viewport widget. QGraphicsView supports affine transformations, using QMatrix. You can either pass a matrix to setMatrix(), or you can call one of the convenience functions rotate(), scale(), translate() or shear(). The most two common transformations are scaling, which is used to implement zooming, and rotation. QGraphicsView keeps the center of the view fixed during a transformation. You can interact with the items on the scene by using the mouse and keyboard. QGraphicsView translates the mouse and key events into \e scene events, (events that inherit QGraphicsSceneEvent,), and forward them to the visualized scene. In the end, it's the individual item that handles the events and reacts to them. For example, if you click on a selectable item, the item will typically let the scene know that it has been selected, and it will also redraw itself to display a selection rectangle. Similiary, if you click and drag the mouse to move a movable item, it's the item that handles the mouse moves and moves itself. Item interaction is enabled by default, and you can toggle it by calling setInteractive(). You can also provide your own custom scene interaction, by creating a subclass of QGraphicsView, and reimplementing the mouse and key event handlers. To simplify how you programmatically interact with items in the view, QGraphicsView provides the mapping functions mapToScene() and mapFromScene(), and the item accessors items() and itemAt(). These functions allow you to map points, rectangles, polygons and paths between view coordinates and scene coordinates, and to find items on the scene using view coordinates. \img graphicsview-view.png \sa QGraphicsScene, QGraphicsItem, QGraphicsSceneEvent*//*! \enum QGraphicsView::ViewportAnchor This enums describe the possible anchors that QGraphicsView can use when the user resizes the view or when the view is transformed. \value NoAnchor No anchor, i.e. the view leaves the scene's position unchanged. \value AnchorViewCenter The scene point at the center of the view is used as the anchor. \value AnchorUnderMouse The point under the mouse is used as the anchor. \sa resizeAnchor, transformationAnchor*//*! \enum QGraphicsView::ViewportUpdateMode \since 4.3 This enum describes how QGraphicsView updates its viewport when the scene contents change or are exposed. \value FullViewportUpdate When any visible part of the scene changes or is reexposed, QGraphicsView will update the entire viewport. This approach is fastest when QGraphicsView spends more time figuring out what to draw than it would spend drawing (e.g., when very many small items are repeatedly updated). This is the preferred update mode for viewports that do not support partial updates, such as QGLWidget. \value MinimalViewportUpdate QGraphicsView will determine the minimal viewport region that requires a redraw, minimizing the time spent drawing by avoiding a redraw of areas that have not changed. This is QGraphicsView's default mode. Although this approach provides the best performance in general, if there are many small visible changes on the scene, QGraphicsView might end up spending more time finding the minimal approach than it will spend drawing. \value SmartViewportUpdate QGraphicsView will attempt to find an optimal update mode by analyzing the areas that require a redraw. \value NoViewportUpdate QGraphicsView will never update its viewport when the scene changes; the user is expected to control all updates. This mode disables all (potentially slow) item visibility testing in QGraphicsView, and is suitable for scenes that either require a fixed frame rate, or where the viewport is otherwise updated externally. \sa viewportUpdateMode*//*! \enum QGraphicsView::OptimizationFlag \since 4.3 This enum describes flags that you can enable to improve rendering performance in QGraphicsView. By default, none of these flags are set. Note that setting a flag usually imposes a side effect, and this effect can vary between paint devices and platforms. \value DontClipPainter QGraphicsView sometimes clips the painter when rendering the scene contents. This can generally improve performance (e.g., rendering only small parts of a large pixmap), and protects against rendering mistakes (e.g., drawing outside bounding rectangles, or outside the exposed area). In some situations, however, the painter clip can slow down rendering; especially when all painting is restricted to inside exposed areas. By enabling this flag, QGraphicsView will completely disable its implicit clipping. Note that rendering artifacts from using a semi-transparent foreground or background brush can occur if clipping is disabled. \value DontSavePainterState When rendering, QGraphicsView protects the painter state (see QPainter::save()) when rendering the background or foreground, and when rendering each item. This allows you to leave the painter in an altered state (i.e., you can call QPainter::setPen() or QPainter::setBrush() without restoring the state after painting). However, if the items consistently do restore the state, you should enable this flag to prevent QGraphicsView from doing the same. \value DontAdjustForAntialiasing Disables QGraphicsView's antialiasing auto-adjustment of exposed areas. Items that render antialiased lines on the boundaries of their QGraphicsItem::boundingRect() can end up rendering parts of the line outside. To prevent rendering artifacts, QGraphicsView expands all exposed regions by 2 pixels in all directions. If you enable this flag, QGraphicsView will no longer perform these adjustments, minimizing the areas that require redrawing, which improves performance. A common side effect is that items that do draw with antialiasing can leave painting traces behind on the scene as they are moved.*//*! \enum QGraphicsView::CacheModeFlag This enum describes the flags that you can set for a QGraphicsView's cache mode. \value CacheNone All painting is done directly onto the viewport. \value CacheBackground The background is cached. This affects both custom backgrounds, and backgrounds based on the backgroundBrush property. When this flag is enabled, QGraphicsView will allocate one pixmap with the full size of the viewport. \sa cacheMode*//*! \enum QGraphicsView::DragMode This enum describes the default action for the view when pressing and dragging the mouse over the viewport. \value NoDrag Nothing happens; the mouse event is ignored. \value ScrollHandDrag The cursor changes into a pointing hand, and dragging the mouse around will scroll the scrolbars. This mode works both in \l{QGraphicsView::interactive}{interactive} and non-interactive mode. \value RubberBandDrag A rubber band will appear. Dragging the mouse will set the rubber band geometry, and all items covered by the rubber band are selected. This mode is disabled for non-interactive views. \sa dragMode, QGraphicsScene::setSelectionArea()*/#include "qgraphicsview.h"#ifndef QT_NO_GRAPHICSVIEW#include "qgraphicsitem.h"#include "qgraphicsitem_p.h"#include "qgraphicsscene.h"#include "qgraphicsscene_p.h"#include "qgraphicssceneevent.h"#include <QtCore/qdatetime.h>#include <QtCore/qdebug.h>#include <QtGui/qapplication.h>#include <QtGui/qdesktopwidget.h>#include <QtGui/qevent.h>#include <QtGui/qlayout.h>#include <QtGui/qtransform.h>#include <QtGui/qmatrix.h>#include <QtGui/qpainter.h>#include <QtGui/qscrollbar.h>#include <QtGui/qstyleoption.h>#include <private/qabstractscrollarea_p.h>#include <math.h>class QGraphicsViewPrivate : public QAbstractScrollAreaPrivate{ Q_DECLARE_PUBLIC(QGraphicsView)public: QGraphicsViewPrivate(); void recalculateContentSize(); void centerView(QGraphicsView::ViewportAnchor anchor); QPainter::RenderHints renderHints; QGraphicsView::DragMode dragMode; bool sceneInteractionAllowed; QRectF sceneRect; bool hasSceneRect; void updateLastCenterPoint(); qint64 horizontalScroll() const; qint64 verticalScroll() const; QList<QGraphicsItem *> itemsInArea(const QPainterPath &path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; QPointF mousePressItemPoint; QPointF mousePressScenePoint; QPoint mousePressViewPoint; QPoint mousePressScreenPoint; QPointF lastMouseMoveScenePoint; QPoint lastMouseMoveScreenPoint; Qt::MouseButton mousePressButton; QTransform matrix; bool accelerateScrolling; qreal leftIndent; qreal topIndent; // Replaying events QGraphicsItem *lastItemUnderCursor; QPointF lastItemUnderCursorPos; // Replaying mouse events QMouseEvent lastMouseEvent; bool useLastMouseEvent; void replayLastMouseEvent(); void storeMouseEvent(QMouseEvent *event); QPointF lastCenterPoint; bool keepLastCenterPoint; Qt::Alignment alignment; QGraphicsView::ViewportAnchor transformationAnchor; QGraphicsView::ViewportAnchor resizeAnchor; QGraphicsView::ViewportUpdateMode viewportUpdateMode; QGraphicsView::OptimizationFlags optimizationFlags; QPointer<QGraphicsScene> scene;#ifndef QT_NO_RUBBERBAND QRect rubberBandRect; QRegion rubberBandRegion(const QWidget *widget, const QRect &rect) const; bool rubberBanding; Qt::ItemSelectionMode rubberBandSelectionMode;#endif bool handScrolling; int handScrollMotions; QGraphicsView::CacheMode cacheMode; QBrush backgroundBrush; QBrush foregroundBrush; QPixmap backgroundPixmap; bool mustResizeBackgroundPixmap; QRegion backgroundPixmapExposed;#ifndef QT_NO_CURSOR QCursor originalCursor; bool hasStoredOriginalCursor; void _q_setViewportCursor(const QCursor &cursor); void _q_unsetViewportCursor();#endif QGraphicsSceneDragDropEvent *lastDragDropEvent; void storeDragDropEvent(const QGraphicsSceneDragDropEvent *event); void populateSceneDragDropEvent(QGraphicsSceneDragDropEvent *dest, QDropEvent *source);};/*! \internal*/QGraphicsViewPrivate::QGraphicsViewPrivate() : renderHints(QPainter::TextAntialiasing), dragMode(QGraphicsView::NoDrag), sceneInteractionAllowed(true), hasSceneRect(false), accelerateScrolling(true), leftIndent(0), topIndent(0), lastItemUnderCursor(0), lastMouseEvent(QEvent::None, QPoint(), Qt::NoButton, 0, 0), useLastMouseEvent(false), keepLastCenterPoint(true), alignment(Qt::AlignCenter), transformationAnchor(QGraphicsView::AnchorViewCenter), resizeAnchor(QGraphicsView::NoAnchor), viewportUpdateMode(QGraphicsView::MinimalViewportUpdate), optimizationFlags(0), scene(0),#ifndef QT_NO_RUBBERBAND
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -