Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Positioning of a QGraphicsItem in QGraphicsView::drawForeground



  • Hello,

    I want to draw a custom QGraphicsItem in the Foreground of my View.
    Therefore I've reimplemented QGraphicsView::drawForeground(QPainter *painter, const QRectF &rect).

    void CustomView::drawForeground(QPainter *painter, const QRectF &rect) {
        painter->drawLine(QLine(QPoint(50, 50), QPoint(100, 100)));
        painter->drawRect(QRect(50, 50, 150, 150));
        QStyleOptionGraphicsItem option;
        customItem.setPos(50, 50);
        customItem.paint(painter, &option, this);
    }
    

    The Line and the Rect which are directly drawn by the painter do have correct positions, but the customItem is always at position (0,0) (scene coordinates).
    The customItem was not added to the scene.

    The paint method of the customItem (inherits from QGraphicsItem) looks like this:

    void CustomItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
        textItem.setPos(QPointF(5, 5)); // is ignored if customItem not added to scene
        textItem.setPlainText(content);
    
        background.setRect(QRect(3, 3, 100, 100)); // strangely background is always set to the correct position
    
        background.paint(painter, option, widget); // only needed if customItem not added to scene
        textItem.paint(painter, option, widget);  // only needed if customItem not added to scene
    }
    

    with

    QString content;
    QGraphicsTextItem textItem;
    QGraphicsRectItem background;
    

    textItem and background do both have the corresponding CustomItem as their parent QGraphicsItem.

    If I previously add the customItem to the QGraphicsScene, then it is drawn at the correct position, but it is drawn twice. One time in the scene and one time in the drawForeground-method.

    Atm I have two approaches in mind to achieve the desired behavior (but both without using QGraphicsView::drawForeground):

    1. adding another overlay scene on top of my normal scene and draw the foreground within this scene (like this: StackOverflow Link)
    2. just add the customItem without parent and with high z-value to the normal scene and update its position in drawBackground (but then it would be part of the scene and not view exclusive)

    Is there a better way to do this with drawForeground?



  • In such a case. setPos is not even ignored at this point, because normally the functions calling the item's paint function will take care of using it. Since you call paint directly, it would be your responsibility to apply the necessary transformations to the painter.

    Why even use a QGraphicsItem in this case, instead of directly calling a paint function? If you do need the QGraphicsItem at other places, you could extract the painting to a separate renderer class, which is then used directly when drawing in the foreground, or inside the item's paint function.


Log in to reply