JtTest
JtTest

Reputation: 187

QPainter's setWorldTransform default behavior?

The following code shows the window on the left (see image below). Nevertheless, uncommenting the line marked with /*[identity transform]*/, the window in the right is generated. As reported by qInfo() in the console output, nothing relevant for the coordinate transform seems to change.

Could anybody explain me the reason? I can't find it in the 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();
}

Console output (for both cases):

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

Result with commented line (left) and with uncommented line (right)

Upvotes: 0

Views: 416

Answers (2)

JtTest
JtTest

Reputation: 187

Reasoning on Marek's answer, I guess to have found a geometrical explaination. My fault was to inspect painter->matrix() rather than painter->transform(). Indeed, Qmatrix does not manage translation, while painter->transform().m31() and painter->transform().m32() do.

Substituting the following lines

qInfo() << painter->transform().m31() << painter->transform().m32();

in place of /*<--->*/ provides console outputs for the two cases, respectively,

99 49

and

0 0

Upvotes: 0

Marek R
Marek R

Reputation: 37927

Paint method uses local coordinate system. This means that origin of painter is usually located at top left corner of QGraphicsItem (note this is base class for everything in QGraphicsScene). In case of QGraphicsEllipseItem it must be center of it.

Apparently this is implemented by transforming QPainter used by QGraphicsView widget when void QWidget::paintEvent(QPaintEvent *event) is processed.

Simply each QGraphicsItem in QGraphicsScene painted by QGraphicsView transform painter for its needs.

When you restore identity transformation, you got a painter in state which applies for QGraphicsView paint event. So it is top left corner of it.

You where lucky that nothing got broken since you are painting outside of boundingRect.

Upvotes: 1

Related Questions