“从矩形中心缩放”不适用于世界变换矩阵

问题描述 投票:0回答:1

我有一个 qtquick 项目,其中有一个 main.qml 和一个 EaDrawArea,它继承自 QQuickPaintedItem,并且可以从 main.qml 访问。 qml中有一个滑块,它绑定到EaDrawArea的m_scale(3到100),我还设置了一个世界变换矩阵

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

m_rate是EaDrawArea的成员,它是1024/20。下面是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)
    }
}

}

构造函数、mousePressEvent和paint函数如下:

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

我想在鼠标光标处绘制一个红色矩形,更重要的是从矩形中心进行缩放。如果我在绘制函数中评论上面两行,则缩放有效,但不能从中心开始。如果我取消上面两行的注释,缩放将从中心开始,但矩形不会在鼠标光标处渲染,为什么?如何解决它(在光标处渲染并从矩形中心缩放)?非常感谢任何帮助,我已询问 gpt 但没有帮助,因为它的建议与我的代码相同。

qt qml scale qt-quick qpainter
1个回答
0
投票

为了帮助降低复杂性,我通常使用锚

Item
,即

    Item {
        x: mouseArea.mouseX
        y: mouseArea.mouseY
    }

然后诸如围绕该锚点项目的缩放和旋转之类的事情将变得微不足道,例如

    MouseArea {
        id: mouseArea
        anchors.fill: parent
        hoverEnabled: true
    }
    Item {
        x: mouseArea.mouseX
        y: mouseArea.mouseY
        Rectangle {
            id: drawingArea
            anchors.centerIn: parent
            color: "red"
            width: sizeSlider.value
            height: sizeSlider.value
            rotation: rotationSlider.value
        }
    }
    Slider { id: sizeSlider; from: 50; to: 200; y: 40 }
    Slider { id: rotationSlider; from: 0; to: 360; y: 80 }

您可以在线尝试!

© www.soinside.com 2019 - 2024. All rights reserved.