Deleting QGraphicsItem with QGraphicsEffect leads to segfault
-
@Chris-Kawa Thank you a lot for your assessment. Also your suggestion fixes the problem.
I have put the
prepareGeometryChange()
intoMyRect
's destructor. I now just delete the item and do not explicitly remove it from the scene.~QGraphicsItem()
does remove itself from the scene and it is called after~MyRect()
. So this is basicly equivalent to what you wrote, but saves the exposure ofprepareGeometryChange()
.The only thing you cannot do now, is to remove the item from the scene without deleting it. I'm going to file a bug report when i have some time.
Thanks again!
-
Check if item bounding rectangle increases if QGraphicsDropShadowEffect is on.
If not this is a problem.
This would be also a reason why calling prepareGeometryChange() helped.
I had similar problem for my custom items if bounding rectangle was not set properly. -
@tfm123 As a workaround you could call setGraphicsEffect(0). before removing item., but this does not guarantee to fix all problems, the same as approach you used.
Problem may still occur in other usage cases which were not found by you yet. Drawing of the item should be always inside the bounding box it reports. -
@tfm123 Why do you create a QGraphicsRectItem instance in the body of the constructor?
MyRect(QGraphicsItem* parent = nullptr): QGraphicsRectItem{QRectF{0.0f, 0.0f, 100.0f, 100.0f}, parent} { setPen(QPen{Qt::white}); setBrush(QBrush{Qt::white, Qt::SolidPattern}); new QGraphicsRectItem{this}; // <-- why this? }
-
@Oleksandr-Malyushytskyy The
boundingRect()
of the rectangle does not change when the effect is applied to it. But the effect itself has aboundingRect()
which changes when the effect is applied. I don't know if this is how it is supposed to be. -
@Oleksandr-Malyushytskyy This is one of the first things I tried and unfortunately it does not help.
-
@aziesemer Got random crashes of QLabel with PixMap + QGraphicsEffect on Ubuntu 18.04 + Qt 5.15.2.
Backtrace:
#0 0x00007ffff1510fb7 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007ffff1512921 in __GI_abort () at abort.c:79
#2 0x00007ffff155b967 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff1688b0d "%s\n") at ../sysdeps/posix/libc_fatal.c:181
#3 0x00007ffff15629da in malloc_printerr (str=str@entry=0x7ffff1686c3a "corrupted double-linked list") at malloc.c:5342
#4 0x00007ffff1562b94 in malloc_consolidate (av=av@entry=0x7ffff18bdc40 <main_arena>) at malloc.c:4486
#5 0x00007ffff156a12b in _int_free (have_lock=0, p=<optimized out>, av=0x7ffff18bdc40 <main_arena>) at malloc.c:4392
#6 0x00007ffff156a12b in __GI___libc_free (mem=0x5555600bf810) at malloc.c:3134
#7 0x00007ffff3f512ba in QImageData::~QImageData() () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Gui.so.5
#8 0x00007ffff3f517a7 in QImage::~QImage() () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Gui.so.5
#9 0x00007ffff3f8b4dc in QRasterPlatformPixmap::~QRasterPlatformPixmap() () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Gui.so.5
#10 0x00007ffff3f8b4f9 in QRasterPlatformPixmap::~QRasterPlatformPixmap() () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Gui.so.5
#11 0x00007ffff3f81091 in QPixmap::~QPixmap() () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Gui.so.5
#12 0x00007ffff3f858b1 in QPixmapCache::remove(QPixmapCache::Key const&) () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Gui.so.5
#13 0x00007ffff4b66165 in QWidgetPrivate::invalidateGraphicsEffectsRecursively() () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Widgets.so.5
#14 0x00007ffff4b661b2 in QWidgetPrivate::setDirtyOpaqueRegion() () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Widgets.so.5
#15 0x00007ffff4b79180 in QWidget::~QWidget() () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Widgets.so.5
#16 0x00007ffff4c6baa9 in QLabel::~QLabel() () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Widgets.so.5Anyone had the same issue?
-
@JoeCFD
after I changed the code in the destructor toif ( nullptr != m_label ) { m_label->setGraphicsEffect( nullptr ); m_label->setVisible( false ); m_label->clear(); delete m_label; m_label = nullptr; }
backtrace results are different now:
(gdb) backtrace
#0 0x00007ffff418e602 in QPainterPath::~QPainterPath() () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Gui.so.5
#1 0x00007ffff4bf61f6 in QRenderRule::~QRenderRule() () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Widgets.so.5
#2 0x00007ffff279e5c9 in QHashData::free_helper(void ()(QHashData::Node)) () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Core.so.5
#3 0x00007ffff279e5c9 in QHashData::free_helper(void ()(QHashData::Node)) () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Core.so.5
#4 0x00007ffff4bf50a3 in QHash<QObject const*, QHash<int, QHash<unsigned long long, QRenderRule> > >::remove(QObject const* const&) () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Widgets.so.5
#5 0x00007ffff4bd8846 in QStyleSheetStyleCaches::objectDestroyed(QObject*) () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Widgets.so.5
#6 0x00007ffff4bd88dc in QStyleSheetStyleCaches::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Widgets.so.5
#7 0x00007ffff2982ddf in void doActivate<false>(QObject*, int, void**) () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Core.so.5
#8 0x00007ffff297c50f in QObject::destroyed(QObject*) () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Core.so.5
#9 0x00007ffff4b7946b in QWidget::~QWidget() () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Widgets.so.5
#10 0x00007ffff4c6baa9 in QLabel::~QLabel() () at /opt/thirdParties/Qt/5.15.2/gcc_64/lib/libQt5Widgets.so.5 -
@JoeCFD did you try the workaround mentioned by @Chris-Kawa ?