James Hao
James Hao

Reputation: 893

"scale from center of rectangle" not work with world transform matrix

I have a qtquick project with a main.qml and an EaDrawArea which inherits from QQuickPaintedItem and is accessible from the main.qml. there is a Slider in the qml which is binding to m_scale (3 to 100) of the EaDrawArea, and I also setup a world transform matrix

(m_rate, 0.0, 0.0,
 0.0, -m_rate, 0.0,
 512.0, 384.0, 1.0)

the m_rate is a member of the EaDrawArea and it is 1024/20. below is the main.qml:

Window {
width: 1200
height: 1000
visible: true
title: qsTr("Hello World")

DrawingArea {
    id: drawarea
    focus: trues
    fillColor: "#dddddd"
    width: 1024
    height: 768
    anchors.left: parent.left
    anchors.leftMargin: 10
    anchors.top: parent.top
    anchors.topMargin: 10

    MouseArea {
        anchors.fill: parent
        onPressed: {
            drawarea.focus = true
            mouse.accepted = false
        }
    }
}

Slider {
    id: scalevalue
    height: 50
    anchors.bottom: parent.bottom
    anchors.horizontalCenter: parent.horizontalCenter
    width: parent.width-10
    anchors.margins: 5
    value: 3.0
    stepSize: 1.0
    minimumValue: 3.0
    maximumValue: 100.0
    onValueChanged: {
        drawarea.setScaleValue(scalevalue.value)
    }
}

}

and the constructor, mousePressEvent and paint function are as below:

   EaDrawArea::EaDrawArea(QQuickItem *parent) {
        m_scale = 3;
        m_rate = 1024.0 / 20.0;
        m_x=0;
        m_y=0;
        m_x1 = 0;
        m_y1 = 0;
        setAcceptedMouseButtons(Qt::AllButtons);
        setAcceptHoverEvents(true);
    }

void EaDrawArea::mousePressEvent(QMouseEvent *event)
{
    m_x = (event->x() - 512.0) / m_rate; // 427 is half of the canvas width (854 / 2)
    m_y = -(event->y() - 384.0) / m_rate; // 240 is half of the canvas height (480 / 2)
    m_x1 = m_x * m_rate / m_scale;
    m_y1 = m_y * m_rate / m_scale;
    this->update(); // Trigger a repaint to draw at the new coordinates
}

void EaDrawArea::paint(QPainter* painter) {
    painter->setRenderHint(QPainter::Antialiasing, true);

    QTransform trans;

    trans.setMatrix(m_rate, 0.0, 0.0,
                    0.0, -m_rate, 0.0,
                    512.0, 384.0, 1.0);
    painter->resetTransform();
    painter->setWorldTransform(trans);

    painter->save();
    QPen redPen(Qt::red);
    redPen.setWidth(1);
    redPen.setCosmetic(true);
    painter->setPen(redPen);

    QRectF rect(m_x1, m_y1, 10, 5);
    QPointF center = rect.center();
    //1. painter->translate(center);
    painter->scale(m_scale/m_rate, m_scale/m_rate);
    //2. painter->translate(-center);
    painter->drawRect(rect);
    painter->restore();
}

I want to draw a red rectangle at mouse cursor and more important to scale from the center of the rectangle. the scaling works but not from the center if I comment above two lines in paint function. and the scaling will be from the center if I uncomment above two lines, but the rectangle will not be rendered at the mouse cursor, why? how to solve it (render at cursor and scale from the center of the rectangle)? very appreciated from any help, I have asked gpt but not help because its suggest is the same my code.

Upvotes: 1

Views: 40

Answers (0)

Related Questions