Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 4

Qt-interest Archive, May 2008
Crash when deleting a QGraphicsProxyWidget (Problem find in Plasma KDE)


Message 1 in thread

Hello,

It's the first time i post here so please give me advices if i'm wrong.

I have noticed a bug during my hacking on plasma. I don't know if it's a bug
so i post here first. The use case is simple : create a proxy widget, delete
it when you click on it.

here the simple code :


#include <QtGui>


class QGraphicsWidgetCrash : public QGraphicsWidget
{
public:
    QGraphicsWidgetCrash(QGraphicsItem * pParent = NULL) :
QGraphicsWidget(pParent)
    {

    }
    ~QGraphicsWidgetCrash()
    {
    }
    void mousePressEvent(QGraphicsSceneMouseEvent * pEvent)
    {
        QGraphicsWidget::mousePressEvent(pEvent);
        deleteLater();
    }
    void paint(QPainter * pPainter, const QStyleOptionGraphicsItem *
pOption,QWidget * pWidget)
    {
        pPainter->drawRect(geometry());
        pPainter->setPen(QColor(Qt::red));

pPainter->drawText(QPointF(geometry().size().width()/2-20,5),QString("CLICK
ME!!!!!!!!!!!!!!!!!!!"));
        QGraphicsWidget::paint(pPainter,pOption,pWidget);
    }
};

int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));

    QGraphicsScene scene;
    scene.setItemIndexMethod(QGraphicsScene::NoIndex);
    QGraphicsWidget * widget = new QGraphicsWidgetCrash();
    QGraphicsLinearLayout * layout = new QGraphicsLinearLayout();
    widget->setLayout(layout);
    QGraphicsProxyWidget * proxy = new
QGraphicsProxyWidget(widget,Qt::Widget);
    QDirModel model;
    QTreeView * tree = new QTreeView;
    tree->setModel(&model);
    proxy->setWidget(tree);
    layout->addItem(proxy);
    widget->resize(300,200);
    scene.addItem(widget);

    QGraphicsView view(&scene);
    view.setRenderHint(QPainter::Antialiasing);
    view.setCacheMode(QGraphicsView::CacheBackground);
    view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
    view.setDragMode(QGraphicsView::ScrollHandDrag);
    view.setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Crash Deleting"));
    view.resize(400, 300);
    view.show();

    return app.exec();
}

I create a ProxyWidget with an QTreeView inside and when i click on it : i
call deleteLater(). First is it a wrong use case? I can do this?

If i run this simple code the program crash. I joined the backtrace in
attachment. It appears on windows and unix.

This crash appears in plasma too of course but i create a "patch". See in
attachement. In the destructor of QGraphicsProxyWidget a setWidget(0) is
call. Some stuff in it seems to be deleted by parent destructor. My patch in
qt-copy solve the problem but it's not a real fix.

Before creating a task in Qt's bug tracker, can someone give me feedbacks?

Thanks.

Best regards.

Darktears.
>	msvcr71d.dll!_NMSG_WRITE(int rterrnum=25)  Ligne 195	C
>	msvcr71d.dll!_NMSG_WRITE(int rterrnum=25)  Ligne 195	C
 	msvcr71d.dll!_amsg_exit(int rterrnum=25)  Ligne 399 + 0x9	C
 	msvcr71d.dll!_purecall()  Ligne 53 + 0x7	C
 	QtGuid4.dll!QGraphicsItem::sceneBoundingRect()  Ligne 2538 + 0x29	C++
 	QtGuid4.dll!QGraphicsScenePrivate::estimateItemsInRect(const QRectF & rect={...})  Ligne 329 + 0xf	C++
 	QtGuid4.dll!QGraphicsScene::items(const QPolygonF & polygon={...}, Qt::ItemSelectionMode mode=IntersectsItemShape)  Ligne 1751 + 0x19	C++
 	QtGuid4.dll!QGraphicsView::items(const QPoint & pos={...})  Ligne 1729 + 0x53	C++
 	QtGuid4.dll!QGraphicsView::itemAt(const QPoint & pos={...})  Ligne 1840 + 0x10	C++
 	QtGuid4.dll!QGraphicsItem::unsetCursor()  Ligne 1303 + 0x35	C++
 	QtGuid4.dll!QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget * newWidget=0x00000000, bool autoShow=true)  Ligne 541	C++
 	QtGuid4.dll!QGraphicsProxyWidget::setWidget(QWidget * widget=0x00b649c8)  Ligne 525	C++
 	00b64980()	
 	QtGuid4.dll!QGraphicsProxyWidget::~QGraphicsProxyWidget()  Ligne 494	C++
 	QGVProxyWidget.exe!QGraphicsProxyWidget::`scalar deleting destructor'()  + 0x10	C++
 	QtGuid4.dll!QGraphicsItem::~QGraphicsItem()  Ligne 773 + 0x1e	C++
 	QtGuid4.dll!QGraphicsWidget::~QGraphicsWidget()  Ligne 197 + 0x48	C++
 	QGVProxyWidget.exe!QGraphicsWidgetCrash::~QGraphicsWidgetCrash()  Ligne 13 + 0x9	C++
 	QGVProxyWidget.exe!QGraphicsWidgetCrash::`scalar deleting destructor'()  + 0xf	C++
 	QtCored4.dll!qDeleteInEventHandler(QObject * o=0x00b64350)  Ligne 3564 + 0x1f	C++
 	QtCored4.dll!QObject::event(QEvent * e=0x00b64948)  Ligne 1093 + 0xc	C++
 	QtGuid4.dll!QGraphicsWidget::event(QEvent * event=0x00b64948)  Ligne 1208	C++
 	QtGuid4.dll!QApplicationPrivate::notify_helper(QObject * receiver=0x00b64350, QEvent * e=0x00b64948)  Ligne 3750 + 0xf	C++
 	QtGuid4.dll!QApplication::notify(QObject * receiver=0x00b64350, QEvent * e=0x00b64948)  Ligne 3344 + 0x10	C++
 	QtCored4.dll!QCoreApplication::notifyInternal(QObject * receiver=0x00b64350, QEvent * event=0x00b64948)  Ligne 561 + 0x13	C++
 	QtCored4.dll!QCoreApplication::sendEvent(QObject * receiver=0x00b64350, QEvent * event=0x00b64948)  Ligne 193 + 0x39	C++
 	QtCored4.dll!QCoreApplicationPrivate::sendPostedEvents(QObject * receiver=0x00000000, int event_type=0, QThreadData * data=0x008e6628)  Ligne 1173 + 0xd	C++
 	QtCored4.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags={...})  Ligne 649 + 0x10	C++
 	QtGuid4.dll!QGuiEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags={...})  Ligne 1071 + 0x15	C++
 	QtCored4.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags={...})  Ligne 128	C++
 	QtCored4.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags={...})  Ligne 174 + 0x16	C++
 	QtCored4.dll!QCoreApplication::exec()  Ligne 823 + 0x15	C++
 	QtGuid4.dll!QApplication::exec()  Ligne 3283	C++
 	QGVProxyWidget.exe!main(int argc=1, char * * argv=0x008e5448)  Ligne 56 + 0x6	C++
 	QGVProxyWidget.exe!WinMain(HINSTANCE__ * instance=0x00400000, HINSTANCE__ * prevInstance=0x00000000, char * __formal=0x001423df, int cmdShow=1)  Ligne 118 + 0x12	C++
 	QGVProxyWidget.exe!WinMainCRTStartup()  Ligne 390 + 0x39	C
 	kernel32.dll!7c816fd7() 	

Attachment:

Attachment: 0229-fix-qgraphicsproxywidget-delete-crash.diff
Description: Binary data