以下代码显示左侧的窗口(请参见下图)。但是,取消注释标记为/*[identity transform]*/的行,将生成右侧的窗口。如控制台输出中qInfo()所报告的,与坐标转换无关的一切似乎都没有改变。

有人可以解释一下原因吗?我在documentation中找不到它。

class SomeItem : public QGraphicsEllipseItem
{
public:
    explicit SomeItem(const QRectF& rect, QGraphicsItem* parent = nullptr) :
        QGraphicsEllipseItem(rect,parent){}

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
               QWidget *widget)
    {
        QTransform tr;
        //painter->setWorldTransform(tr); /*[identity transform]*/
        qInfo() << painter->window().left() << painter->window().right()
                << painter->window().top() << painter->window().bottom();
        qInfo() << painter->viewport().left() << painter->viewport().right()
                << painter->viewport().top() << painter->viewport().bottom();
        qInfo() << painter->matrix().m11() << painter->matrix().m12()
                << painter->matrix().m21() << painter->matrix().m22();
        /* <--->*/
        QGraphicsEllipseItem::paint(painter,option,widget);
    }
};

int main(int argc, char **argv)
{
    QApplication app (argc, argv);

    QGraphicsScene ms;
    ms.setSceneRect(-20,-20,40,40);
    SomeItem* si = new SomeItem(QRectF(-10,-10,20,20));
    ms.addItem(si);
    QGraphicsView view(&ms);
    view.show();

    return app.exec();
}


控制台输出(两种情况):

0 197 0 97
0 197 0 97
1 0 0 1


c&#43;&#43; - QPainter的setWorldTransform默认行为?-LMLPHP

最佳答案

绘制方法使用局部坐标系。这意味着painter的来源通常位于QGraphicsItem的左上角(请注意,这是QGraphicsScene中所有内容的基类)。如果是QGraphicsEllipseItem,它必须位于它的中心。

显然,这是通过在处理void QWidget::paintEvent(QPaintEvent *event)时转换QPainter小部件使用的QGraphicsView来实现的。

只需将QGraphicsItem绘制的QGraphicsScene中的每个QGraphicsView转换为画家即可。

恢复身份转换时,您的画家处于申请QGraphicsView绘画事件的状态。所以它在它的左上角。

您很幸运,因为您在boundingRect之外进行绘画,所以没有任何损坏。

关于c++ - QPainter的setWorldTransform默认行为?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55283613/

10-11 16:18