⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qgraphicsscene.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************** 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.******************************************************************************/static const int QGRAPHICSSCENE_INDEXTIMER_TIMEOUT = 2000;/*!    \class QGraphicsScene    \brief The QGraphicsScene class provides a surface for managing a large    number of 2D graphical items.    \since 4.2    \ingroup multimedia    \mainclass    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 \l{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:    \code        QGraphicsScene scene;        scene.addText("Hello, world!");        QGraphicsView view(&scene);        view.show();    \endcode    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. 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.    \section1 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 \e {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 \e {hover    events}. If an item accepts hover events (see    QGraphicsItem::acceptsHoverEvents()), it will receive a \l    {QEvent::}{GraphicsSceneHoverEnter} event when the mouse enters    its area. As the mouse continues moving inside the item's area,    QGraphicsScene will send it \l {QEvent::}{GraphicsSceneHoverMove}    events. When the mouse leaves the item's area, the item will    receive a \l {QEvent::}{GraphicsSceneHoverLeave} event.    All mouse events are delivered to the current \e {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.    \sa QGraphicsItem, QGraphicsView*//*!    \enum QGraphicsScene::SceneLayer    \since 4.3    This enum describes the rendering layers in a QGraphicsScene. When    QGraphicsScene draws the scene contents, it renders each of these layers    separately, in order.    Each layer represents a flag that can be OR'ed together when calling    functions such as invalidate() or QGraphicsView::invalidateScene().    \value ItemLayer The item layer. QGraphicsScene renders all items are in    this layer by calling the virtual function drawItems(). The item layer is    drawn after the background layer, but before the foreground layer.    \value BackgroundLayer The background layer. QGraphicsScene renders the    scene's background in this layer by calling the virtual function    drawBackground(). The background layer is drawn first of all layers.    \value ForegroundLayer The foreground layer. QGraphicsScene renders the    scene's foreground in this layer by calling the virtual function    drawForeground().  The foreground layer is drawn last of all layers.    \value AllLayers All layers; this value represents a combination of all    three layers.    \sa invalidate(), QGraphicsView::invalidateScene()*//*!    \enum QGraphicsScene::ItemIndexMethod    This enum describes the indexing algorithms QGraphicsScene provides for    managing positional information about items on the scene.    \value BspTreeIndex A Binary Space Partitioning tree is applied. All    QGraphicsScene's item location algorithms are of an order close to    logarithmic complexity, by making use of binary search. Adding, moving and    removing items is logarithmic. This approach is best for static scenes    (i.e., scenes where most items do not move).    \value NoIndex No index is applied. Item location is of linear complexity,    as all items on the scene are searched. Adding, moving and removing items,    however, is done in constant time. This approach is ideal for dynamic    scenes, where many items are added, moved or removed continuously.    \sa setItemIndexMethod(), bspTreeDepth*/#include "qgraphicsscene.h"#ifndef QT_NO_GRAPHICSVIEW#include "qgraphicsitem.h"#include "qgraphicsitem_p.h"#include "qgraphicsscene_p.h"#include "qgraphicssceneevent.h"#include "qgraphicsview.h"#include <private/qobject_p.h>#include <QtCore/qcoreapplication.h>#include <QtCore/qlist.h>#include <QtCore/qrect.h>#include <QtCore/qset.h>#include <QtCore/qtimer.h>#include <QtGui/qevent.h>#include <QtGui/qtransform.h>#include <QtGui/qmatrix.h>#include <QtGui/qpainter.h>#include <QtGui/qpaintengine.h>#include <QtGui/qpolygon.h>#include <QtGui/qstyleoption.h>#include <QtGui/qtooltip.h>#include <math.h>#include <qdebug.h>// QRectF::intersects() returns false always if either the source or target// rectangle's width or height are 0. This works around that problem.static QRectF _q_adjustedRect(const QRectF &rect){    static const qreal p = 0.00001;    QRectF r = rect;    if (!r.width())        r.adjust(-p, 0, p, 0);    if (!r.height())        r.adjust(0, -p, 0, p);    return r;}/*!    \internal*/QGraphicsScenePrivate::QGraphicsScenePrivate()    : indexMethod(QGraphicsScene::BspTreeIndex),      bspTreeDepth(0),      lastItemCount(0),      hasSceneRect(false),      updateAll(false),      calledEmitUpdated(false),      selectionChanging(0),      regenerateIndex(true),      purgePending(false),      indexTimerId(0),      restartIndexTimer(false),      hasFocus(false),      focusItem(0),      lastFocusItem(0),      mouseGrabberItem(0),      lastMouseGrabberItem(0),      dragDropItem(0),      lastDropAction(Qt::IgnoreAction){}/*!    \internal*/QList<QGraphicsItem *> QGraphicsScenePrivate::estimateItemsInRect(const QRectF &rect) const{    Q_Q(const QGraphicsScene);    const_cast<QGraphicsScenePrivate *>(this)->purgeRemovedItems();    if (indexMethod == QGraphicsScene::BspTreeIndex) {        // ### Only do this once in a while.        QGraphicsScenePrivate *that = const_cast<QGraphicsScenePrivate *>(this);        // Get items from BSP tree        QList<QGraphicsItem *> items = that->bspTree.items(rect);        // Fill in with any unindexed items        for (int i = 0; i < unindexedItems.size(); ++i) {            if (QGraphicsItem *item = unindexedItems.at(i)) {                QRectF boundingRect = _q_adjustedRect(item->sceneBoundingRect());                if (!item->d_ptr->itemDiscovered && item->isVisible()                    && (boundingRect.intersects(rect) || boundingRect.contains(rect))) {                    item->d_ptr->itemDiscovered = 1;                    items << item;                }            }        }        // Reset the discovered state of all discovered items        for (int i = 0; i < items.size(); ++i)            items.at(i)->d_func()->itemDiscovered = 0;        return items;    }    QList<QGraphicsItem *> itemsInRect;    foreach (QGraphicsItem *item, q->items()) {        QRectF boundingRect = _q_adjustedRect(item->sceneBoundingRect());        if (item->isVisible() && (boundingRect.intersects(rect) || boundingRect.contains(rect)))            itemsInRect << item;    }    return itemsInRect;}/*!    \internal*/void QGraphicsScenePrivate::addToIndex(QGraphicsItem *item){    if (indexMethod == QGraphicsScene::BspTreeIndex) {        if (item->d_func()->index != -1) {            bspTree.insertItem(item, item->sceneBoundingRect());            foreach (QGraphicsItem *child, item->children())                child->addToIndex();        } else {            // The BSP tree is regenerated if the number of items grows to a            // certain threshold, or if the bounding rect of the graph doubles in            // size.            startIndexTimer();        }    }}/*!    \internal*/void QGraphicsScenePrivate::removeFromIndex(QGraphicsItem *item){    if (indexMethod == QGraphicsScene::BspTreeIndex) {        int index = item->d_func()->index;        if (index != -1) {            bspTree.removeItem(item, item->sceneBoundingRect());            freeItemIndexes << index;            indexedItems[index] = 0;            item->d_func()->index = -1;            unindexedItems << item;            foreach (QGraphicsItem *child, item->children())                child->removeFromIndex();        }        startIndexTimer();    }}/*!    \internal*/void QGraphicsScenePrivate::resetIndex(){    purgeRemovedItems();    if (indexMethod == QGraphicsScene::BspTreeIndex) {        for (int i = 0; i < indexedItems.size(); ++i) {            if (QGraphicsItem *item = indexedItems.at(i)) {                item->d_ptr->index = -1;                unindexedItems << item;            }        }        indexedItems.clear();        freeItemIndexes.clear();        regenerateIndex = true;        startIndexTimer();    }}static inline int intmaxlog(int n){    return  (n > 0 ? qMax(int(::ceil(::log(double(n)) / ::log(double(2)))), 5) : 0);}/*!

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -