问题
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() < 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); }
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