Planned maintenance has been done but it did not solve the problem. So work will continue on this and a new time for trying updates will be announced asap.

QGraphicsView/Scene paints over other widgets



  • Hi!
    In my Qt application, I use a QGraphicsView with a QGraphicsScene, which is larger than the viewport (I can scroll and zoom).
    In my QGraphicsView derived class source file, I do

    void GraphWidget::drawForeground(QPainter *painter, const QRectF &rect){
            QPen pen(QColor(qRgb(145, 187, 255)));
            pen.setCapStyle(Qt::RoundCap);
            pen.setStyle(Qt::DotLine);
            painter->setPen(pen);
            painter->drawPath( getPainterPath() );
    }
    

    But as you can see on the picture, these lines also get painted over widgets, that are not part of the QGraphicsView (the QGraphicsView is one slot to the left in a horizontal box layout, so it actually shouldn't be "behind" the widgets or something like that).

    0_1545945146707_Qt 41.png

    You can also see, that the lines are not even drawn correctly (all lines should be curved).
    Is this a bug, or did I do anything wrong? How can I avoid that?
    Thanks for answers!



  • update
    So, it really seems to be a qt bug.
    I just found this post: https://stackoverflow.com/questions/39376050/strange-painting-bug-in-graphicsview-in-pyqt-5-7

    The workaround is described there: just set the opacity of the proxy-item to just below 1 like

        proxy = new QGraphicsProxyWidget(this);
        proxy->setWidget(new QLineEdit);
        proxy->setScale(0.35);
        proxy->setOpacity(0.999999);
        graph->scene()->addItem(proxy);
    

    and it all works perfectly well now.

    There is also the url to the bug report: https://bugreports.qt.io/browse/QTBUG-55918
    So, this issue should be fixed for Qt ver 5.9.6
    I just installed Qt 5.12 and tried it and it works now without the workaround
    Thank you for your help!


  • Lifetime Qt Champion

    Hi
    Normally one does not draw directly to the view but uses items to do the drawing.
    However, there is
    http://doc.qt.io/qt-5/qgraphicsview.html#drawForeground
    and
    http://doc.qt.io/qt-5/qgraphicsview.html#drawBackground
    to paint over entire view.
    But what is the goal of the lines ?



  • @mrjj
    Thanks! Yes, I do use QGraphicsItems, but these lines are just for connecting some of these items and I don't want to create QGraphicsItems for these lines (because they are just some primitive lines, no functionality at all). So these lines are the only thing, I draw on the scene directly (in MyQGraphicsView::drawForeground())


  • Lifetime Qt Champion

    Hi
    Oh, so you are already using drawForeground ?
    That is odd. Normally no artifact comes from that.
    What Qt version are you using ?



  • @mrjj said in QGraphicsView/Scene paints over other widgets:

    Oh, so you are already using drawForeground ?

    Jep, already using it, sorry, I updated the question.

    What Qt version are you using ?

    I'm using Qt 5.9.1 (but these problems already occured in older versions)


  • Lifetime Qt Champion

    Hi
    I tested with Diagram example.
    alt text

    class MyView : public QGraphicsView
    {
        Q_OBJECT
    public:
        explicit MyView(QWidget *parent = nullptr);
    signals:
    protected:
        virtual void drawForeground(QPainter *painter, const QRectF &rect) override
        {
            QPen pen(Qt::red);
            pen.setCapStyle(Qt::RoundCap);
            painter->setPen(pen);
            int bsize = 200;
            int numBox = 50 * bsize;
            for (int x = 0; x < numBox; x += bsize) {
                for (int y = 0; y < numBox; y += bsize) {
                    QRect r(x, y, bsize, bsize);
                    painter->drawRect( r );
                }
    
            }
    
        }
    };
    
    

    Also tried
    QSize si=viewport()->size();
    painter->drawLine(0,0,si.width(),si.height());

    Which also draw as expected.

    So im not rally sure what you are seeing.
    Also, it sounds like it draws outside QGraphicsView which is very odd.

    Its it possible to make a small example that shows this issue so
    we can test ?



  • @mrjj Thank you!

    Yes, after a while I just figured out, where the problem comes from.
    In my application, I use a splitter layout (GraphicsView left, other widgets right). There is no problem with painting in the View and in the items. The problem occurs when I use QGraphicsProxyWidgets.
    If I create a proxy and place it in the scene like

    MyGraphicsView::MyGraphicsView(QWidget *parent) :
        QGraphicsView(parent)
    {
        QGraphicsScene *scene = new QGraphicsScene(this);
        scene->setItemIndexMethod(QGraphicsScene::NoIndex);
        scene->setSceneRect(-1750, -1000, 3500, 2105);
    
        setScene(scene);
        setCacheMode( CacheBackground );
        setViewportUpdateMode(BoundingRectViewportUpdate);
        setRenderHint((QPainter::Antialiasing));
        setTransformationAnchor(AnchorUnderMouse);
        scale(qreal(4.0), qreal(4.0));
        
        QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget();
        proxy->setWidget(new QLineEdit);
        proxy->setScale(0.35);
        scene->addItem(proxy);
    }
    

    this proxy is in the scene in the middle position (0,0). Now it gets funny. If the proxy is not visable in the viewport (because I scrolled elsewhere), everything works just fine.

    0_1546001212845_Qt 44.png

    But if the proxy is visable, the problems occur as described (but only after I took the splitter-handle between the "myGraph" and the GroupBox on the right and resize the layout)

    0_1546001262216_Qt 45.png

    Any idea, what is causing Qt to do these things when using proxywidgets?



  • @Niagarer said in QGraphicsView/Scene paints over other widgets:

    @mrjj
    Thanks! Yes, I do use QGraphicsItems, but these lines are just for connecting some of these items and I don't want to create QGraphicsItems for these lines (because they are just some primitive lines, no functionality at all). So these lines are the only thing, I draw on the scene directly (in MyQGraphicsView::drawForeground())

    Unless you have a better reason, I advise drawing everything that belongs into the scene inside the scene (using QGraphicsItem derived classes). Otherwise, you add unnecessary complexity that may hurt you later in subtle ways.

    If you feel that you don't need individual line items, you could create a single QGraphicsItem that draw all such lines for the whole scene.



  • @Asperamanca
    Of course, I could draw the lines by a QGraphicsItem, but I guess it wouldn't solve the proxy-problem.
    The following code leads to the same result, despite I give the QGraphicsItem as parent to the QGraphicsProxyWidget

    MyGraphicsView.cpp:

    MyGraphicsView::MyGraphicsView(QWidget *parent) :
        QGraphicsView(parent)
    {
        QGraphicsScene *scene = new QGraphicsScene(this);
        scene->setItemIndexMethod(QGraphicsScene::NoIndex);
        scene->setSceneRect(-1750, -1000, 3500, 2105);
    
        setScene(scene);
        setCacheMode( CacheBackground );
        setViewportUpdateMode(BoundingRectViewportUpdate);
        setRenderHint((QPainter::Antialiasing));
        setTransformationAnchor(AnchorUnderMouse);
        scale(qreal(4.0), qreal(4.0));
    
        MyGraphicsItem *item = new MyGraphicsItem(this);
        scene->addItem(item);
    }
    

    MyGraphicsItem.cpp:

    MyGraphicsItem::MyGraphicsItem(MyGraphicsView *graph)
    {
        proxy = new QGraphicsProxyWidget(this);
        proxy->setWidget(new QLineEdit);
        proxy->setScale(0.35);
        graph->scene()->addItem(proxy);
    }
    


  • update
    So, it really seems to be a qt bug.
    I just found this post: https://stackoverflow.com/questions/39376050/strange-painting-bug-in-graphicsview-in-pyqt-5-7

    The workaround is described there: just set the opacity of the proxy-item to just below 1 like

        proxy = new QGraphicsProxyWidget(this);
        proxy->setWidget(new QLineEdit);
        proxy->setScale(0.35);
        proxy->setOpacity(0.999999);
        graph->scene()->addItem(proxy);
    

    and it all works perfectly well now.

    There is also the url to the bug report: https://bugreports.qt.io/browse/QTBUG-55918
    So, this issue should be fixed for Qt ver 5.9.6
    I just installed Qt 5.12 and tried it and it works now without the workaround
    Thank you for your help!


  • Lifetime Qt Champion

    @Niagarer
    Good found. :)