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 dovoid 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).
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-7The 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! -
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()) -
@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)
-
Hi
I tested with Diagram example.
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 likeMyGraphicsView::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.
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)
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 QGraphicsProxyWidgetMyGraphicsView.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-7The 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!