QGraphicsView and QGraphicsItem: don´t scale item when scaling the view rect

后端 未结 5 1620
既然无缘
既然无缘 2021-02-04 13:46

I am using Qt´s QGraphicsView - and QGraphicsItem-subclasses. is there a way to not scale the graphical representation of the item in the view when the

相关标签:
5条回答
  • 2021-02-04 14:03

    Set the QGraphicItem's flag QGraphicsItem::ItemIgnoresTransformations to true does not work for you?

    0 讨论(0)
  • 2021-02-04 14:12

    I found that if I derive a new class and reimpliment the paint function I can do

    void MyDerivedQGraphicsItem::paint(QPainter *painter, 
                                       const QStyleOptionGraphicsItem *option, 
                                       QWidget *widget)
    {
      double scaleValue = scale();
      double scaleX = painter->transform().m11();
      setScale(scaleValue / scaleX);
      QGraphicsSvgItem::paint(painter,option,widget);
    }
    

    This is the best way of doing it that I have found so far, but I am still tinkering around.

    0 讨论(0)
  • 2021-02-04 14:15

    The following solution worked perfectly for me:

    void MyDerivedQGraphicsItem::paint(QPainter *painter, const StyleOptionGraphicsItem *option, QWidget *widget)
    {
        double scaleValue = scale()/painter->transform().m11();
        painter->save();
        painter->scale(scaleValue, scaleValue);
        painter->drawText(...);
        painter->restore();
        ...
    }
    

    We can also multiply the scaleValue by other mesures we want to keep its size constant outside the save/restore environment.

        QPointF ref(500, 500);
        QPointF vector = scaleValue * QPointF(100, 100);
        painter->drawLine(ref+vector, ref-vector);
    
    0 讨论(0)
  • 2021-02-04 14:19

    How about this:

    #include <QtGui/QApplication>
    #include <QtGui/QGraphicsScene>
    #include <QtGui/QGraphicsView>
    #include <QtGui/QGraphicsRectItem>
    
    int main(int argc, char* argv[]) {
        QApplication app(argc, argv);
        QGraphicsScene scene;
        scene.addText("Hello, world!");
        QRect rect(50, 50, 100, 100);
        QGraphicsRectItem* recti = scene.addRect(rect);
        QGraphicsView view(&scene);
    
        // Set scale for the view
        view.scale(10.0, 5.0);
    
        // Set the inverse transformation for the item
        recti->setTransform(view.transform().inverted());
    
        view.show();
        return app.exec();
    }
    

    As you can see the text is scaled up but the rectangle is not. Note that this does not only prevent the scaling for the rectangle but and other transformation.

    0 讨论(0)
  • 2021-02-04 14:22

    I got into the same problem, and it took me a while to figure it out. This is how I solved it.

    Extend a QGraphicsItem class, override paint(). Inside the paint(), reset the transformation's scaling factor to 1(which are m11 and m22), and save the m11(x scaling factor) and m22(y scaling factor) before the reset. Then, draw like you would normally do but multiply your x with m11 and y with m22. This avoids drawing with the default transformation, but explicitly calculates the positions according to the scene's transformation.

    void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget)
    {
        QTransform t = painter->transform();
        qreal m11 = t.m11(), m22 = t.m22();
        painter->save(); // save painter state
        painter->setTransform(QTransform(m11, t.m12(), t.m13(),
                                         t.m21(), 1, t.m23(), t.m31(),
                                         t.m32(), t.m33()));
        int x = 0, y = 0; // item's coordinates
        painter->drawText(x*m11, y*m22, "Text"); // the text itself will not be scaled, but when the scene is transformed, this text will still anchor correctly
        painter->restore(); // restore painter state
    }
    

    The following code block is drawing with default transformation

    void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget)
    {
        int x = 0, y = 0;
        painter->drawText(x, y, "Text"); 
    }
    

    You can try both to see the difference. Hope this helps.

    0 讨论(0)
提交回复
热议问题