如何在QGraphicsScene中添加项目?

时间:2011-08-03 07:08:20

标签: qt4 qgraphicsscene

我试图在鼠标点击和鼠标光标坐标上在QGraphicsScene中添加一些自定义QGraphicsItems。但是这些项目不会添加到与鼠标光标相同的坐标处。


    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是自定义QGraphicsItem的QGraphicsView和Clothoids


    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() < ePoint.x()) && (sPoint.y() < 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() < 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() < 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);
        }

我猜我插入项目的坐标属于GraphicsView,而不是我的应用程序中的场景,场景不会覆盖整个视图。但是我怎么能在我的情况下获得场景的坐标?

1 个答案:

答案 0 :(得分:2)

你是对的,坐标是相对于GraphicView而不是Scene

取自Qt's documentation

  

返回鼠标光标相对于接收事件的窗口小部件的位置。   如果由于鼠标事件而移动窗口小部件,请使用globalPos()返回的全局位置以避免抖动。

希望它们提供便利功能(excerpt from the QGraphicsView doc):

  

您还可以通过创建QGraphicsView的子类并重新实现鼠标和键事件处理程序来提供自己的自定义场景交互。为了简化以编程方式与视图中的项进行交互的方式,QGraphicsView提供了映射函数mapToScene()和mapFromScene(),以及项访问器items()和itemAt()。这些函数允许您在视图坐标和场景坐标之间映射点,矩形,多边形和路径,并使用视图坐标在场景中查找项目。

所以,您正在寻找的函数是mapToScene(),您可以直接调用,因为renderArea继承自QGraphicsView

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

修改:注意,mapToScene()会返回QPointF,而不是QPoint。本身不是问题,但你应该意识到这一点。