Details
-
Bug
-
Resolution: Out of scope
-
P2: Important
-
4.6.3
-
None
-
Windows XP 64 bit, QT 4.6.3 build for win 32 with MS VC 2005
Description
When scene itemIndexMethod () is set to NoIndex, at least two QGraphicsItem items are created with the same ZValue, then last created item ZValue is changed to lower value (in other words order of items to be displayed changed), call to scene clear after scene was displayed once ( I did it in scene destructor ) leads to access violation at:
void QGraphicsScene::clear()
{ Q_D(QGraphicsScene); // NB! We have to clear the index before deleting items; otherwise the // index might try to access dangling item pointers. d->index->clear(); // NB! QGraphicsScenePrivate::unregisterTopLevelItem() removes items while (!d->topLevelItems.isEmpty()) delete d->topLevelItems.first(); // <<<<<<< here is garbage pointer ................. } Problem can be reproduced with modified diagramscene project from Qt/examples (in attachment). When example run it will add 2 items to the scene ( you can see them if you scroll window). Then simply close window, clear() will be called in destructor when you close window. Attempt to delete second item in clear will result in access violation. delete d->topLevelItems.first(); // <<<<<<< here is garbage pointer The key changes: Added call to initSceneForCrash() function in constructor; //! [0] DiagramScene::DiagramScene(QMenu *itemMenu, QObject *parent) : QGraphicsScene(parent) { myItemMenu = itemMenu; myMode = MoveItem; myItemType = DiagramItem::Step; line = 0; textItem = 0; myItemColor = Qt::white; myTextColor = Qt::black; myLineColor = Qt::black; initSceneForCrash(); // ! [test 1] }void DiagramScene::initSceneForCrash()
{
setItemIndexMethod ( NoIndex );
QGraphicsRectItem * item;
// Create 2 partially overlapping items
qreal x0 = 50;
qreal y0 = 50;
qreal a = 200;
qreal b = 440;
qreal height = 55.;
qreal angle =0.;
item = insertTestRectangle( x0, y0, a ,b, height, angle );
this->addItem( item );
x0 = 100;
y0 = 100;
item = insertTestRectangle( x0, y0, a ,b, height, angle );
this->addItem( item );
// set item ZValue so it goes below 1st item
item->setZValue( 15 );
}
QGraphicsRectItem * DiagramScene::insertTestRectangle( qreal x0, qreal y0, qreal a ,qreal b, qreal height, qreal angle ) {
QGraphicsRectItem *item = this->addRect( 0, 0, a, b );
item->setFlags( QGraphicsItem::ItemIsMovable|QGraphicsItem::ItemIsSelectable );
int z = qrand()%256;
item->setBrush( QColor(z,z,10, 128) );
item->setPen( QPen(QColor(qrand()%32*8,qrand()%32*8,qrand()%32*8), 2) );
item->setZValue( height );
item->setPos( x0, y0 );
if( angle != qreal(0.) )
item->setRotation( angle );
return item;
}