Good day

I have an application that is running fine on Qt 4.5 under both Windows and Linux, but when trying to compile it with Qt 4.6 or later, it hangs when calling QGraphicsScene::update() function inside grandchild object

The hierarchy of the design as follow
QGraphicsScene(DrawerScene), which has one object of type QGraphicsRectItem(PageItem)
in the pageItem we can add multiple QGraphicsPixmapItemobjects (DroppedItem)

DroppedItem can be selected, resized, and moved.

This is the dropEvent code in the PageItem class
Qt Code:
  1. void PageItem::dropEvent(QGraphicsSceneDragDropEvent * event)
  2. {
  3. // verify that we drop an image.
  4. if (event->mimeData()->hasImage())
  5. {
  6. QPointF pt = event->pos(); //QPointF pt = mapToItem(this, event->pos());
  7.  
  8. QByteArray byteArray = event->mimeData()->data("image/jpg");
  9. QPixmap pixmap = QPixmap::fromImage( QImage::fromData(byteArray, "jpg") );
  10. new DroppedItem(pixmap, pt, 1.0, this);
  11. }
  12. }
To copy to clipboard, switch view to plain text mode 
in the DroppedItem class, the hang happens in the paint function when calling the update function of the scene object, as in the code below

Qt Code:
  1. void DroppedItem::paint(QPainter *painter, const QStyleOptionGraphicsItem
  2. *option, QWidget *widget)
  3. {
  4. painter->drawImage(boundingRect().toRect(),getScaledImage());
  5.  
  6. //the line below works OK for Qt 4.5, but hangs (on Linux) for Qt 4.6, 4.7)
  7. //the line below is needed to update the scene so that it reflects this item is
  8. //being resized.
  9. //I've tried to comment it, and add it to the zoom function (see full code below),
  10. //but it does not reflect the same behavior.
  11. scene()->update(scene()->itemsBoundingRect());
  12. }
To copy to clipboard, switch view to plain text mode 

Below is the full source code for the DroppedItem.cpp file, I can provide any other info if needed.
Qt Code:
  1. #include "droppeditem.h"
  2. #include "pageitem.h"
  3.  
  4. #include <QKeyEvent>
  5. #include <QtDebug>
  6. #include <QTime>
  7. #include <QGraphicsScene>
  8. #include <QMessageBox>
  9. #include <QPainter>
  10.  
  11. DroppedItem::DroppedItem(const QPixmap & pixmap, const QPointF & scenePos, qreal perc, QGraphicsItem * parent /*=0*/) :
  12. QGraphicsPixmapItem(pixmap, parent),
  13. m_originalPixmap(pixmap),
  14. m_imageWidth(m_originalPixmap.width())
  15. {
  16. // set position with scene position.
  17. setPos(scenePos);
  18. setZValue(0.9);
  19. // make the item selectable, movable & focusable
  20. setFlag(QGraphicsItem::ItemIsSelectable, true);
  21. setFlag(QGraphicsItem::ItemIsMovable, true);
  22. setFlag(QGraphicsItem::ItemIsFocusable,true);
  23.  
  24. m_pageItem = static_cast<PageItem*> (parentItem());
  25.  
  26. setPixmap(m_originalPixmap);
  27. m_originalImage = m_originalPixmap.toImage();
  28. }
  29.  
  30. DroppedItem::~DroppedItem()
  31. {
  32. }
  33.  
  34. int DroppedItem::type() const
  35. {
  36. return Type;
  37. }
  38.  
  39. void DroppedItem::keyPressEvent(QKeyEvent * event)
  40. {
  41. if (event->key() == Qt::Key_Delete && isSelected())
  42. {
  43. // remove item when key press event is Suppr.
  44. scene()->removeItem(this);
  45. return;
  46. }
  47. else
  48. {
  49. //check if the new position is within the boundary of the page
  50. QGraphicsPixmapItem::keyPressEvent(event);
  51. }
  52. }
  53.  
  54. void DroppedItem::zoom(int value)
  55. {
  56. m_currentValue = value;
  57. update(this->boundingRect().toRect());
  58. }
  59.  
  60. void DroppedItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
  61. {
  62. if (event->button() != Qt::LeftButton)
  63. {
  64. event->ignore();
  65. return;
  66. }
  67.  
  68. checkBoundary(event->pos().toPoint(), true);
  69. if(m_tweakingpart != "")
  70. m_tweaking = true;
  71.  
  72. QGraphicsPixmapItem::mousePressEvent(event);
  73. }
  74.  
  75. void DroppedItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
  76. {
  77. if(m_tweaking)
  78. {
  79. QPoint pt = event->pos().toPoint();
  80. m_rectangle = this->boundingRect().toRect();
  81. qreal value = 1.0;
  82. if ( m_tweakingpart == "bottomRight" ) { m_rectangle . setBottomRight ( pt ) ; value = static_cast<qreal> (m_rectangle.height() / (m_originalPixmap.height()*1.0) );}
  83. else if ( m_tweakingpart == "bottom" ) { m_rectangle . setBottom ( pt . y () ) ; value = static_cast<qreal> (m_rectangle.height() / (m_originalPixmap.height()*1.0) );}
  84. else if ( m_tweakingpart == "right" ) { m_rectangle . setRight ( pt . x () ) ; value = static_cast<qreal> (m_rectangle.width() / (m_originalPixmap.width() *1.0) );}
  85.  
  86. zoom(value*100);
  87. }
  88. else
  89. {
  90. QGraphicsPixmapItem::mouseMoveEvent(event);
  91. }
  92. }
  93.  
  94. void DroppedItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
  95. {
  96. m_tweaking = false ;
  97. m_tweakingpart = "" ;
  98.  
  99. setCursor(QCursor(Qt::OpenHandCursor));
  100. QPointF pt = pos();
  101. checkBoundary(pt.x(), pt.y());
  102. QGraphicsPixmapItem::mouseReleaseEvent(event);
  103. }
  104.  
  105. void DroppedItem::checkBoundary(QPoint pt, bool t)
  106. {
  107. m_rectangle = this->boundingRect().toRect();
  108.  
  109. if ( m_rectangle.isValid() )
  110. {
  111. QPoint m_tl = m_rectangle.topLeft();
  112. QPoint m_tr = m_rectangle.topRight();
  113. QPoint m_bl = m_rectangle.bottomLeft();
  114. QPoint m_br = m_rectangle.bottomRight();
  115.  
  116. const QPoint off(20, 20), offx(20, -20), offy(-20, 20);
  117.  
  118. if( QRect( m_br-off, m_br+off).contains(pt) )
  119. {
  120. if (t)
  121. m_tweakingpart = "bottomRight" ;
  122. this->setCursor( Qt::SizeFDiagCursor );
  123. }
  124. else if( QRect( m_bl+offx, m_br-offx ).contains(pt) )
  125. {
  126. if (t)
  127. m_tweakingpart = "bottom";
  128. this->setCursor( Qt::SizeVerCursor ) ;
  129. }
  130. else if( QRect( m_tr+offy, m_br-offy ).contains(pt) )
  131. {
  132. if (t)
  133. m_tweakingpart = "right";
  134. this->setCursor( Qt::SizeHorCursor );
  135. }
  136. }
  137. }
  138.  
  139. void DroppedItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
  140. {
  141. painter->drawImage(boundingRect().toRect(),getScaledImage());
  142. //this causes the program to hang when compiled with Qt >= 4.6
  143. //(I checked only on Linux, but I think it will hang on Windows as well)
  144. scene()->update(scene()->itemsBoundingRect());
  145. }
  146.  
  147. QRectF DroppedItem::boundingRect() const
  148. {
  149. qreal w = (m_currentValue/100.0) * m_originalPixmap.width();
  150. qreal h = (m_currentValue/100.0) * m_originalPixmap.height();
  151. return QRectF(QPointF(0,0), QPointF(w, h));
  152. }
  153.  
  154.  
  155. QImage DroppedItem::getScaledImage()
  156. {
  157. qreal w = (m_currentValue/100.0) * m_originalPixmap.width();
  158. qreal h = (m_currentValue/100.0) * m_originalPixmap.height();
  159.  
  160. QSizeF size(w, h);
  161. QImage image(size.toSize(), QImage::Format_RGB888);
  162.  
  163. image = m_originalImage.scaledToWidth(w, Qt::SmoothTransformation);
  164. return image;
  165. }
To copy to clipboard, switch view to plain text mode