1

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

    renderArea::renderArea(QWidget *parent):
            QGraphicsView(父)
    {
        场景 = 新 QGraphicsScene(this);
        场景->setItemIndexMethod(QGraphicsScene::NoIndex);
        场景->setSceneRect(0, 0, 850, 480);
        设置场景(场景);
        setCacheMode(CacheBackground);
        setViewportUpdateMode(BoundingRectViewportUpdate);
        setRenderHint(QPainter::抗锯齿);
        setTransformationAnchor(AnchorUnderMouse);
        规模(qreal(1.0),qreal(1.0));
        setMinimumSize(400, 400);
    }

    无效渲染区域::mousePressEvent(QMouseEvent *事件)
    {
        QPoint p = event->pos();

    更新列表(p);
    }

    void renderArea::updateList(const QPoint &p)
    {
        点点;
        点.点 = p;
        点.isSelected = false;
        list.append(point);
        如果 (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);

        场景->添加项目(临时);
    }

renderArea 是 QGraphicsView 和 Clothoids 自定义 QGraphicsItem

    Clothoid::Clothoid(QPoint startPoint, QPoint endPoint)
    {
        sPoint = 起点;
        ePoint = 端点;
        起始曲率 = 0.0;
        结束曲率 = 0.0;
        ClooidLength = sqrt(pow(endPoint.x() - startPoint.x(),2) +
                              pow(endPoint.y() - startPoint.y(),2));
    }    

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

            如果 ((sPoint.x() < ePoint.x()) && (sPoint.y() < ePoint.y()))
                返回 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()))
                返回 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()))
                返回 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()))
                返回 QRectF(ePoint.x(), ePoint.y(), sPoint.x() - ePoint.x(), sPoint.y() - ePoint.y())
                .normalized()
                .adjusted(-penWidth, -penWidth, penWidth, penWidth);

            返回 QRectF();

        }

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

            // 自己画线
            画家->setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
            画家->画线(线);
        }

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

4

1 回答 1

2

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

取自Qt 的文档

返回鼠标光标的位置,相对于接收事件的小部件。如果您因鼠标事件而移动小部件,请使用 globalPos() 返回的全局位置来避免晃动。

希望它们提供方便的功能(摘自 QGraphicsView 文档):

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

因此,您要查找的函数是mapToScene(),您可以直接调用它,因为 renderArea 继承自 QGraphicsView

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

编辑:当心,mapToScene()返回 a QPointF,而不是 a QPoint。本身不是问题,但您应该意识到这一点。

于 2011-08-03T12:11:46.930 回答