Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用QGraphicsEffect删除QGraphicsItem会导致segfault_C++_Qt_Qgraphicsitem - Fatal编程技术网

C++ 使用QGraphicsEffect删除QGraphicsItem会导致segfault

C++ 使用QGraphicsEffect删除QGraphicsItem会导致segfault,c++,qt,qgraphicsitem,C++,Qt,Qgraphicsitem,以下程序绘制红色背景。按下鼠标左键可在其上绘制一个白色矩形。该矩形有一个子矩形和一个QGraphicsDropShadowEffect。(QGraphicsOpacityEffect和QGraphicsColorizeEffect也会导致该问题,但频率较低。) 按鼠标右键可删除白色矩形 有时删除矩形会导致分割错误 如果未应用QGraphicsDropShadowEffect,则不会发生这种情况。如果MyRect中没有子项,或者后台被复制,也不会发生这种情况 (在搜索此问题时,我发现了一些提示,表

以下程序绘制红色背景。按下鼠标左键可在其上绘制一个白色矩形。该矩形有一个子矩形和一个
QGraphicsDropShadowEffect
。(
QGraphicsOpacityEffect
QGraphicsColorizeEffect
也会导致该问题,但频率较低。)

按鼠标右键可删除白色矩形

有时删除矩形会导致分割错误

如果未应用
QGraphicsDropShadowEffect
,则不会发生这种情况。如果
MyRect
中没有子项,或者后台被复制,也不会发生这种情况

(在搜索此问题时,我发现了一些提示,表明像这样的segfault可能与在不调用
prepareGeometryChange()
的情况下更改项的
boundingRect()
有关)

我在这里真是不知所措。这是一个更大项目的一部分,我将其归结为以下示例:

Main.cc:

#include<QApplication>
#include<QGraphicsView>
#include<QGraphicsScene>
#include<QGraphicsSceneMouseEvent>
#include<QGraphicsRectItem>
#include<QGraphicsDropShadowEffect>
#include<QScreen>

class MyRect: public QGraphicsRectItem
{
    public:
    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});
        my_child_=new QGraphicsRectItem{this};
    }

    private:
    QGraphicsRectItem* my_child_=nullptr;
};

class MyScene: public QGraphicsScene
{
    public:
    MyScene()
    {
        background_=new QGraphicsRectItem{0.0f, 0.0f, 500.0f, 500.0f};
        background_->setPen(QPen{Qt::white});
        background_->setBrush(QBrush{Qt::red, Qt::SolidPattern});
        addItem(background_);
    }

    void mouseReleaseEvent(QGraphicsSceneMouseEvent* me) override
    {
        if (me->button()==Qt::LeftButton)
        {
            if (my_rect_==nullptr)
            {
                my_rect_=new MyRect{};
                shadow_=new QGraphicsDropShadowEffect{};
                shadow_->setBlurRadius(15.0f);
                my_rect_->setGraphicsEffect(shadow_);
                addItem(my_rect_);
                my_rect_->setPos(me->scenePos());
            }
        }
        else if (me->button()==Qt::RightButton)
        {
            if (my_rect_!=nullptr)
            {
                removeItem(my_rect_);
                my_rect_->setGraphicsEffect(0);
                shadow_=nullptr;
                delete my_rect_;
                my_rect_=nullptr;
            }
        }
        else
        {
            QGraphicsScene::mouseReleaseEvent(me);
        }
    }

    private:
    QGraphicsRectItem* background_=nullptr;
    MyRect* my_rect_=nullptr;
    QGraphicsDropShadowEffect* shadow_=nullptr;
};

int
main(int argc, char** argv)
{
    QApplication qapp{argc, argv};

    QGraphicsView view;
    MyScene scene;

    QRect rect=QGuiApplication::primaryScreen()->geometry();
    scene.setSceneRect(0.0f, 0.0f, rect.width(), rect.height());
    view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    view.setFrameShape(QFrame::NoFrame);
    view.setBackgroundBrush(QBrush(Qt::black, Qt::SolidPattern));
    view.setScene(&scene);
    view.showFullScreen();

    return qapp.exec();
}
回溯:

#0  0x0000555555a9a840 in ?? ()
#1  0x00007ffff71e017c in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#2  0x00007ffff71e0a3a in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#3  0x00007ffff720289a in QGraphicsView::paintEvent(QPaintEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#4  0x00007ffff6f10278 in QWidget::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#5  0x00007ffff6ff89fe in QFrame::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#6  0x00007ffff72013ab in QGraphicsView::viewportEvent(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#7  0x00007ffff7650701 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#8  0x00007ffff6ec8b65 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#9  0x00007ffff6ed0341 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#10 0x00007ffff76509a0 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#11 0x00007ffff6f08fda in QWidgetPrivate::sendPaintEvent(QRegion const&) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#12 0x00007ffff6f09646 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#13 0x00007ffff6ed8f1e in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#14 0x00007ffff6ed9147 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#15 0x00007ffff6ef7f8f in QWidgetPrivate::syncBackingStore() () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#16 0x00007ffff6f10348 in QWidget::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#17 0x00007ffff6ff89fe in QFrame::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#18 0x00007ffff7081de3 in QAbstractScrollArea::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#19 0x00007ffff6ec8b8c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#20 0x00007ffff6ed0341 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#21 0x00007ffff76509a0 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#22 0x00007ffff765312d in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#23 0x00007ffff71d2a22 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#24 0x00007ffff71d8299 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#25 0x00007ffff767d459 in QObject::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#26 0x00007ffff71e4e6b in QGraphicsScene::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#27 0x00007ffff6ec8b8c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#28 0x00007ffff6ed0341 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#29 0x00007ffff76509a0 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#30 0x00007ffff765312d in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#31 0x00007ffff76a4c03 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#32 0x00007ffff446f7f7 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#33 0x00007ffff446fa60 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#34 0x00007ffff446fb0c in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#35 0x00007ffff76a500f in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#36 0x00007ffff764e98a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#37 0x00007ffff76570fc in QCoreApplication::exec() () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#38 0x000055555555768b in main (argc=1, argv=0x7fffffffe5b8) at Main.cc:89
#0 0x000055555A9A840英寸??()
#1 0x00007FF71E017C英寸??()来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#2 0x00007FF71E0A3A英寸??()来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5的QGraphicsView::paintEvent(QPaintEvent*)()中的3 0x00007ffff720289a
#来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5的QWidget::event(QEvent*)()中的4 0x00007ffff6f10278
#来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5的QFrame::event(QEvent*)()中的5 0x00007ffff6ff89fe
#来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5的QGraphicsView::viewportEvent(QEvent*)()中的6 0x00007FF72013ab
#来自/usr/lib/x86_64-linux-gnu/libQt5Core.so.5的QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*,QEvent*)()中的7 0x00007FF7650701
#来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so的QApplicationPrivate::notify_helper(QObject*,QEvent*)()中的8 0x00007ffff6ec8b65。5
#来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so的QApplication::notify(QObject*,QEvent*)()中的9 0x00007ffff6ed0341
#10 0x00007FF76509A0在/usr/lib/x86_64-linux-gnu/libQt5Core.so.5的QCoreApplication::notifyInternal2(QObject*,QEvent*)中
#11/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5中QWidgetPrivate::sendPaintEvent(QRegion const&)中的0x00007ffff6f08fda
#QWidgetPrivate::drawWidget中的12 0x00007ffff6f09646(QPaintDevice*、QRegion const&、QPoint const&、int、QPainter*、QWidgetBackingStore*)()
来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#13 0x00007ffff6ed8f1e英寸??()来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#14 0x00007ffff6ed9147英寸??()来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5的QWidgetPrivate::syncBackingStore()中的15 0x00007ffff6ef7f8f
#来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5的QWidget::event(QEvent*)()中的16 0x00007ffff6f10348
#来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5的QFrame::event(QEvent*)()中的17 0x00007ffff6ff89fe
#来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5的QAbstractScrollArea::event(QEvent*)()中的18 0x00007ffff7081de3
#19/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5中QApplicationPrivate::notify_helper(QObject*,QEvent*)()中的0x00007ffff6ec8b8c
#来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5的QApplication::notify(QObject*,QEvent*)()中的20 0x00007ffff6ed0341
#21 0x00007FF76509A0在/usr/lib/x86_64-linux-gnu/libQt5Core.so.5的QCoreApplication::notifyInternal2(QObject*,QEvent*)中
#来自/usr/lib/x86_64-linux-gnu/libQt5Core.so.5的QCoreApplicationPrivate::sendPostedEvents(QObject*,int,QThreadData*))中的22 0x00007FF765312d
#23 0x00007FF71D2A22英寸??()来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#24 0x00007FF71D8299英寸??()来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#来自/usr/lib/x86_64-linux-gnu/libQt5Core.so.5的QObject::event(QEvent*)()中的25 0x00007ff767d459
#26/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5中qgraphicscene::event(QEvent*)()中的0x00007ff71e4e6b
#QApplicationPrivate::notify_helper(QObject*,QEvent*)中的27 0x00007ffff6ec8b8c,来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#来自/usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5的QApplication::notify(QObject*,QEvent*)()中的28 0x00007ffff6ed0341
#来自/usr/lib/x86_64-linux-gnu/libQt5Core.so.5的QCoreApplication::notifyInternal2(QObject*,QEvent*)中的29 0x00007ff76509a0
#来自/usr/lib/x86_64-linux-gnu/libQt5Core.so.5的QCoreApplicationPrivate::sendPostedEvents(QObject*,int,QThreadData*))中的30 0x00007FF765312d
#31 0x00007FF76A4C03英寸??()来自/usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#32 0x00007FF446F7位于/lib/x86\u 64-linux-gnu/libglib-2.0.so.0的g_主上下文中
#33 0x00007FF446FA60英寸??()来自/lib/x86_64-linux-gnu/libglib-2.0.so.0
#34 0x00007FF446FB0C位于/lib/x86\u 64-linux-gnu/libglib-2.0.so.0中的g_主上下文迭代()中
#来自/usr/lib/x86_64-linux-gnu/libQt5Core.so.5的QEventDispatcherGlib::processEvents(QFlags)()中的35 0x00007ff76a500f
#来自/usr/lib/x86_64-linux-gnu/libQt5Core.so.5的QEventLoop::exec(QFlags)()中的36 0x00007ffff764e98a
#来自/usr/lib/x86_64-linux-gnu/libQt5Core.so.5的QCoreApplication::exec()中的37 0x00007FF76570fc
#干管中的38 0x0000555768B(argc=1,argv=0x7fffffe5b8)位于干管中。cc:89
编辑:为了更好的可读性,我重新编写了代码示例。

因为我接受了关于这不是预期行为的教育,可能是Qt中的错误

最好的解决方法是在将其从场景中删除之前,在
my_rect
上调用
QGraphicsItem::prepareGeometryChange()
。这可以通过公开受保护的
prepareGeometryChange()
或在
~MyRect()
内调用它,然后简单地删除
MyRect
,而不调用
qgraphicscenscene::removietem()
~QGraphicsItem()
,当然是在
~MyRect()
之后调用,它将
#0  0x0000555555a9a840 in ?? ()
#1  0x00007ffff71e017c in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#2  0x00007ffff71e0a3a in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#3  0x00007ffff720289a in QGraphicsView::paintEvent(QPaintEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#4  0x00007ffff6f10278 in QWidget::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#5  0x00007ffff6ff89fe in QFrame::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#6  0x00007ffff72013ab in QGraphicsView::viewportEvent(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#7  0x00007ffff7650701 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#8  0x00007ffff6ec8b65 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#9  0x00007ffff6ed0341 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#10 0x00007ffff76509a0 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#11 0x00007ffff6f08fda in QWidgetPrivate::sendPaintEvent(QRegion const&) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#12 0x00007ffff6f09646 in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, int, QPainter*, QWidgetBackingStore*) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#13 0x00007ffff6ed8f1e in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#14 0x00007ffff6ed9147 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#15 0x00007ffff6ef7f8f in QWidgetPrivate::syncBackingStore() () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#16 0x00007ffff6f10348 in QWidget::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#17 0x00007ffff6ff89fe in QFrame::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#18 0x00007ffff7081de3 in QAbstractScrollArea::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#19 0x00007ffff6ec8b8c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#20 0x00007ffff6ed0341 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#21 0x00007ffff76509a0 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#22 0x00007ffff765312d in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#23 0x00007ffff71d2a22 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#24 0x00007ffff71d8299 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#25 0x00007ffff767d459 in QObject::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#26 0x00007ffff71e4e6b in QGraphicsScene::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#27 0x00007ffff6ec8b8c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#28 0x00007ffff6ed0341 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#29 0x00007ffff76509a0 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#30 0x00007ffff765312d in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#31 0x00007ffff76a4c03 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#32 0x00007ffff446f7f7 in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#33 0x00007ffff446fa60 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#34 0x00007ffff446fb0c in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#35 0x00007ffff76a500f in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#36 0x00007ffff764e98a in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#37 0x00007ffff76570fc in QCoreApplication::exec() () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#38 0x000055555555768b in main (argc=1, argv=0x7fffffffe5b8) at Main.cc:89