How to add item in a QGraphicsScene?

南楼画角 提交于 2019-12-11 06:54:21

问题


I am trying to add some custom QGraphicsItems in a QGraphicsScene on mouse click and at mouse cursor coordinates. But the items are not added at the same coordinates as the mouse cursor's.


    renderArea::renderArea(QWidget *parent):
            QGraphicsView(parent)
    {
        scene = new QGraphicsScene(this);
        scene->setItemIndexMethod(QGraphicsScene::NoIndex);
        scene->setSceneRect(0, 0, 850, 480);
        setScene(scene);
        setCacheMode(CacheBackground);
        setViewportUpdateMode(BoundingRectViewportUpdate);
        setRenderHint(QPainter::Antialiasing);
        setTransformationAnchor(AnchorUnderMouse);
        scale(qreal(1.0), qreal(1.0));
        setMinimumSize(400, 400);
    }

    void renderArea::mousePressEvent(QMouseEvent *event)
    {
        QPoint p = event->pos();

    updateList(p);
    }

    void renderArea::updateList(const QPoint &p)
    {
        Point point;
        point.point = p;
        point.isSelected = false;
        list.append(point);
        if (list.size() > 1)
            updateClothoid(list[list.size()-2].point, list[list.size()-1].point);
    }

    void renderArea::updateClothoid(const QPoint &p1, const QPoint &p2)
    {
        Clothoid *temp = new Clothoid(p1, p2);

        clothoids.append(temp);

        scene->addItem(temp);
    }

renderArea being the QGraphicsView and Clothoids the custom QGraphicsItem


    Clothoid::Clothoid(QPoint startPoint, QPoint endPoint)
    {
        sPoint = startPoint;
        ePoint = endPoint;
        startCurvature = 0.0;
        endCurvature = 0.0;
        clothoidLength = sqrt(pow(endPoint.x() - startPoint.x(),2) +
                              pow(endPoint.y() - startPoint.y(),2));
    }    

    QRectF Clothoid::boundingRect() const
        {
            qreal penWidth = 1;

            if ((sPoint.x() &lt ePoint.x()) && (sPoint.y() &lt ePoint.y()))
                return QRectF(sPoint.x(), sPoint.y(), ePoint.x() - sPoint.x(), ePoint.y()-sPoint.y())
                .normalized()
                .adjusted(-penWidth, -penWidth, penWidth, penWidth);

            if ((sPoint.x() &lt ePoint.x()) && (sPoint.y() > ePoint.y()))
                return QRectF(sPoint.x(), ePoint.y(), ePoint.x() - sPoint.x(), sPoint.y() - ePoint.y())
                .normalized()
                .adjusted(-penWidth, -penWidth, penWidth, penWidth);

            if ((sPoint.x() > ePoint.x()) && (sPoint.y() &lt ePoint.y()))
                return QRectF(ePoint.x(), sPoint.y(), sPoint.x() - ePoint.x(), ePoint.y()-sPoint.y())
                .normalized()
                .adjusted(-penWidth, -penWidth, penWidth, penWidth);

            if ((sPoint.x() > ePoint.x()) && (sPoint.y() > ePoint.y()))
                return QRectF(ePoint.x(), ePoint.y(), sPoint.x() - ePoint.x(), sPoint.y() - ePoint.y())
                .normalized()
                .adjusted(-penWidth, -penWidth, penWidth, penWidth);

            return QRectF();

        }

        void Clothoid::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
        {
            QLineF line(sPoint, ePoint);

            // Draw the line itself
            painter->setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
            painter->drawLine(line);
        }

I am guessing that the coordinates to which I am inserting the items belong to the GraphicsView and not the scene as in my application the scene doesn't cover the entire view. But how could I get the coordinates of the scene in my case?


回答1:


You're right, the coordinates are relative to the GraphicView, not the Scene

Taken from the Qt's documentation :

Returns the position of the mouse cursor, relative to the widget that received the event. If you move the widget as a result of the mouse event, use the global position returned by globalPos() to avoid a shaking motion.

Hopefully, they provide convenience functions (excerpt from the QGraphicsView doc) :

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.

So, the function you're looking for is mapToScene() that you can call directly because renderArea inherits from QGraphicsView

void renderArea::mousePressEvent(QMouseEvent *event)
{
    QPoint p = mapToScene(event->pos());
    updateList(p);
}

Edit : Watch out, mapToScene() returns a QPointF, not a QPoint. Not a problem in itself, but you should be aware of this.



来源:https://stackoverflow.com/questions/6922821/how-to-add-item-in-a-qgraphicsscene

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!