Strange graphics scene bug in Qt 5.7?
-
We are hoping to upgrade to PyQt 5.7/Qt 5.7 but have this one nasty issue left to fix, and it looks like it could be at the Qt level. I have created a minimal Qt app using PyQt to reproduce the problem (see my post on stackoverflow). Here is what the view looks like:
This shows a graphics view containing two graphics items, each one identical (although that doesn't matter), and each one contains one proxy widget item (which can contain anything, here it contains a label) and one ellipse item (again could be anything like rectangle, poly etc). The image clearly shows how the ellipse "bleeds" into the surrounding area!
I converted the Python code from this example to C++, but I don't have a C++ dev env readily available and have not built Qt apps before (I have only used Qt from PyQt, albeit in rather large apps). So there may be a couple little compilation errors, can anyone try to make this build, then report if they can see the bug (and post the fixed code)? Here is the code:
#include <QApplication> #include <QtCore> #include <QtWidgets> #include <QtGui> class MyGraphicsItem: public QGraphicsObject { public: MyGraphicsItem::MyGraphicsItem() { # next line could be any type of graphics item: QGraphicsEllipseItem* rect_item = QGraphicsEllipseItem(0, 0, 100, 100, this); # effect easier to see if paint black: rect_item->setBrush(QBrush(Qt.SolidPattern)); QGraphicsProxyWidget* label_item = QGraphicsProxyWidget(this); # *** Next line must be there for effect to be visible, but could be any other type of widget label_item->setWidget(new QLabel('a'*30)); } QRectF boundingRect() const Q_DECL_OVERRIDE { return childrenBoundingRect(); } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) Q_DECL_OVERRIDE { } private: QBrush* __default_brush; QGraphicsRectItem* __widget_rect; QGraphicsProxyWidget* __part_item; QPainterPath* __background_path; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); QWidget widget; QHBoxLayout* layout = QHBoxLayout(); widget.setLayout(layout) QGraphicsView* view = new QGraphicsView(); MyScene* scene = new QGraphicsScene(); scene.addItem(MyGraphicsItem()) # *** effect only there if more than 1 item scene.addItem(MyGraphicsItem()) view->setScene(scene); layout->addWidget(view); widget.setGeometry(100, 100, 50, 50) widget.show(); return app.exec(); }
-
Hi,
There's indeed something strange going on.
You should check the bug report system to see if it something know.
Here's a buildable version of your code:
#include <QApplication> #include <QtCore> #include <QtWidgets> #include <QtGui> class MyGraphicsItem: public QGraphicsObject { public: MyGraphicsItem() { // # next line could be any type of graphics item: QGraphicsEllipseItem* rect_item = new QGraphicsEllipseItem(0, 0, 100, 100, this); // # effect easier to see if paint black: rect_item->setBrush(QBrush(Qt::SolidPattern)); QGraphicsProxyWidget* label_item = new QGraphicsProxyWidget(this); //# *** Next line must be there for effect to be visible, but could be any other type of widget label_item->setWidget(new QLabel("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); } QRectF boundingRect() const Q_DECL_OVERRIDE { return childrenBoundingRect(); } private: QBrush* __default_brush; QGraphicsRectItem* __widget_rect; QGraphicsProxyWidget* __part_item; QPainterPath* __background_path; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); QWidget widget; QHBoxLayout* layout = new QHBoxLayout(); widget.setLayout(layout); QGraphicsView* view = new QGraphicsView(); QGraphicsScene* scene = new QGraphicsScene(); scene->addItem(new MyGraphicsItem());// # *** effect only there if more than 1 item scene->addItem(new MyGraphicsItem()); view->setScene(scene); layout->addWidget(view); widget.setGeometry(100, 100, 50, 50); widget.show(); return app.exec(); }
-
Hi,
There's indeed something strange going on.
You should check the bug report system to see if it something know.
Here's a buildable version of your code:
#include <QApplication> #include <QtCore> #include <QtWidgets> #include <QtGui> class MyGraphicsItem: public QGraphicsObject { public: MyGraphicsItem() { // # next line could be any type of graphics item: QGraphicsEllipseItem* rect_item = new QGraphicsEllipseItem(0, 0, 100, 100, this); // # effect easier to see if paint black: rect_item->setBrush(QBrush(Qt::SolidPattern)); QGraphicsProxyWidget* label_item = new QGraphicsProxyWidget(this); //# *** Next line must be there for effect to be visible, but could be any other type of widget label_item->setWidget(new QLabel("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); } QRectF boundingRect() const Q_DECL_OVERRIDE { return childrenBoundingRect(); } private: QBrush* __default_brush; QGraphicsRectItem* __widget_rect; QGraphicsProxyWidget* __part_item; QPainterPath* __background_path; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); QWidget widget; QHBoxLayout* layout = new QHBoxLayout(); widget.setLayout(layout); QGraphicsView* view = new QGraphicsView(); QGraphicsScene* scene = new QGraphicsScene(); scene->addItem(new MyGraphicsItem());// # *** effect only there if more than 1 item scene->addItem(new MyGraphicsItem()); view->setScene(scene); layout->addWidget(view); widget.setGeometry(100, 100, 50, 50); widget.show(); return app.exec(); }
Awesome, thanks so much for doing this. Indeed I found a bug report that is surely the same problem, and points to a workaround that seems to work in PyQt 5.7 example app and our full PyQt app, can you try this patch to confirm on the C++ side:
... label_item->setWidget(new QLabel("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); label_item->setOpacity(0.99999); // ADD THIS LINE
Not a fix but an acceptable workaround, hopefully the Qt bug gets addressed eventually.