Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Drawing a straight QGraphicsRectItem when scene rotated (mouse move issue)



  • Hello,
    the problem I'm trying to solve relates to drawing a rectangle when the view has been rotated. Basically, I have a scene where I draw a QGraphicsRectItem. The rect item should always be 'straight', ie. sides are parallel to the screen sides. When I rotate my view, the rectangle that I draw should always be drawn 'straight'. I do this by creating my new rect item with the opposite view rotation. This works based on the following code snippet:
    @
    void SketchScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
    {
    _mousePressPoint = mouseEvent->scenePos();
    rectangle = new RectItem(QRectF(_mousePressPoint, _mousePressPoint));
    rectangle->setPen( QPen(_penColor, _penSize, _penStyle) ) ;
    rectangle->setTransformOriginPoint(_mousePressPoint);
    rectangle->setRotation(-currentViewRotationSum); //fix rotation angle
    addItem(rectangle) ;
    }
    void SketchScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
    {
    QPointF mouseMove = mouseEvent->scenePos();
    QRectF newRect(_mousePressPoint, mouseEvent->scenePos());
    rectangle->setRect( newRect );
    }
    @

    PROBLEM: when the rotation is greater than 45 degrees, the mouse position with respect to where the upper left corner of the rectangle is drawn is way off. This is very confusing for the user.

    How can I fix it so that the upper left corner of the rectangle is always following the mouse location when it is moved even when the view is rotated?

    Thanks in advance for your help,
    Conrad :)



  • OK, I figured it out. In case somebody else comes across this issue it's quite simple with Qt.

    PROBLEM: when the view is rotated and you are trying to draw a QGraphicsRectItem so that sides are parallel to the monitor you use setRotation() and setTransformOriginPoint() in the opposite direction of the rotated view. The problem is that when you drag the mouse to enlarge the rectangle, the mouse location and rectangle corner are separated by the rotation amount. This is very annoying.

    SOLUTION: Use "sceneTransform()":http://qt-project.org/doc/qt-4.8/qgraphicsitem.html#sceneTransform to place the mouse in the correct place.
    Referring to the original code above the solution is the following:

    @
    void SketchScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
    {
    _mousePressPoint = mouseEvent->scenePos();
    rectangle = new RectItem(QRectF(_mousePressPoint, _mousePressPoint));
    rectangle->setPen( QPen(_penColor, _penSize, _penStyle) ) ;
    rectangle->setTransformOriginPoint(_mousePressPoint);
    rectangle->setRotation(-currentViewRotationSum); //fix rotation angle
    addItem(rectangle) ;
    }

    void SketchScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
    {
    QPointF mouseMove = mouseEvent->scenePos();
    QPointF moveMousePoint = rectangle->sceneTransform().inverted().map(mouseMove);
    int minX = _mousePressPoint.x();
    int minY = _mousePressPoint.y();
    int maxX = moveMousePoint.x();
    int maxY = moveMousePoint.y();
    if(maxX < minX)
    {
    maxX = minX;
    minX = moveMousePoint.x();
    }
    if(maxY < minY)
    {
    maxY = minY;
    minY = moveMousePoint.y();
    }
    QRectF newRect(minX, minY, maxX - minX, maxY - minY);

       rectangle->setRect( newRect );
    

    }
    @

    Hope this helps!
    Conrad :)


Log in to reply