Results 1 to 12 of 12

Thread: call to QGraphicsScene::update() hangs when compiled with Qt4.6

  1. #1
    Join Date
    Jul 2009
    Location
    Jordan, and UAE
    Posts
    55
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default call to QGraphicsScene::update() hangs when compiled with Qt4.6

    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 

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: call to QGraphicsScene::update() hangs when compiled with Qt4.6

    Have you set a breakpoint to see if calling scene()->update() from within the DroppedItem:aint() method isn't resulting in an infinite loop?

  3. #3
    Join Date
    Jul 2009
    Location
    Jordan, and UAE
    Posts
    55
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: call to QGraphicsScene::update() hangs when compiled with Qt4.6

    setting a breakpoint where?
    thanks

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: call to QGraphicsScene::update() hangs when compiled with Qt4.6

    What sense does it make to update a scene from a painting routine? To me it seems you should just add a call to prepareGeometryChange() at the end of your DroppedItem::zoom() method instead of the call to update() there.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Jul 2009
    Location
    Jordan, and UAE
    Posts
    55
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: call to QGraphicsScene::update() hangs when compiled with Qt4.6

    Good day Wysota
    I've done that, it now does not hang, and it updates correctly, but I have one issue that shows with this solution

    When I change the size of the dropped item, it changes, and resizes correctly. but then, the new boundaries are not detected by mouse events, for example, if the original rect was 50X50, and after resizing it became 100X100, the mouseMoveEvent, mousePressEvent, mouseReleaseEvent and mouseDoubleClickEvent will only detect area within the old boundaries, even it does shows correctly.
    even if the mouse if over the new area, the mouse pointer belongs to the parent item (PageItem).

    Any suggestions?
    Thanks

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: call to QGraphicsScene::update() hangs when compiled with Qt4.6

    Quote Originally Posted by yazwas View Post
    When I change the size of the dropped item, it changes, and resizes correctly. but then, the new boundaries are not detected by mouse events, for example, if the original rect was 50X50, and after resizing it became 100X100, the mouseMoveEvent, mousePressEvent, mouseReleaseEvent and mouseDoubleClickEvent will only detect area within the old boundaries, even it does shows correctly.
    even if the mouse if over the new area, the mouse pointer belongs to the parent item (PageItem).
    Does your implementation of boundingRect() reflect those changes properly? How did you implement it?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #7
    Join Date
    Jul 2009
    Location
    Jordan, and UAE
    Posts
    55
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: call to QGraphicsScene::update() hangs when compiled with Qt4.6

    Quote Originally Posted by wysota View Post
    Does your implementation of boundingRect() reflect those changes properly? How did you implement it?
    Hi
    This is how I implemented it, and also you can see the full source code in the original posting above


    Qt Code:
    1. QRectF DroppedItem::boundingRect() const
    2. {
    3. qreal w = (m_currentValue/100.0) * m_originalPixmap.width();
    4. qreal h = (m_currentValue/100.0) * m_originalPixmap.height();
    5. return QRectF(QPointF(0,0), QPointF(w, h));
    6. }
    To copy to clipboard, switch view to plain text mode 

    regards,

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: call to QGraphicsScene::update() hangs when compiled with Qt4.6

    And where are you calling prepareGeometryChange()?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  9. #9
    Join Date
    Jul 2009
    Location
    Jordan, and UAE
    Posts
    55
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: call to QGraphicsScene::update() hangs when compiled with Qt4.6

    Quote Originally Posted by wysota View Post
    And where are you calling prepareGeometryChange()?
    As you suggested, I used it in the zoom function instead of call to update. I've also added it to mouseMoveEvent function, but that also did not change anything.

    any suggestions?
    thanks

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: call to QGraphicsScene::update() hangs when compiled with Qt4.6

    Everything should work fine then. If it doesn't then apparently your mouseMoveEvent() is incorrectly implemented.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  11. #11
    Join Date
    Jul 2009
    Location
    Jordan, and UAE
    Posts
    55
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: call to QGraphicsScene::update() hangs when compiled with Qt4.6

    Quote Originally Posted by wysota View Post
    Everything should work fine then. If it doesn't then apparently your mouseMoveEvent() is incorrectly implemented.
    can you look at the code posted earlier (in the first post), the logic behind it is as follow
    on mousePressEvent(), I check for boundary, if its on the borders, then moseMoveEvent() updates the rectangle
    my problem is even the rectangle is resized, but the mouse over the new area, will remain show the mouse cursor that belongs to the pageItem object

    regards

  12. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: call to QGraphicsScene::update() hangs when compiled with Qt4.6

    Your logic is too complicated. It's much easier to do this in the scene and using transformation system built into the GraphicsView architecture.

    There is some flaw in my code but nevertheles it works most of the time so it's something to base your solution upon:

    Qt Code:
    1. #include <QtGui>
    2.  
    3. class Scene : public QGraphicsScene {
    4. public:
    5. Scene() {
    6. activeItem = 0;
    7. }
    8.  
    9. protected:
    10. void mousePressEvent(QGraphicsSceneMouseEvent *me) {
    11. activeItem = itemAt(me->scenePos());
    12. if(activeItem) {
    13. QRectF sR = activeItem->sceneBoundingRect();
    14. if(me->pos().x() < sR.left()+10
    15. || me->pos().x() > sR.right()-10
    16. || me->pos().y() < sR.top()+10
    17. || me->pos().y() > sR.bottom()-10)
    18. {
    19.  
    20. } else activeItem = 0;
    21. }
    22. QGraphicsScene::mousePressEvent(me);
    23. }
    24.  
    25. void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
    26. activeItem = 0;
    27. QGraphicsScene::mouseReleaseEvent(event);
    28. }
    29.  
    30. void mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
    31. if(activeItem) {
    32. QPointF scPos = event->scenePos();
    33. QPointF lastScPos = event->lastScenePos();
    34. QRectF sR = activeItem->sceneBoundingRect();
    35. //qreal aspectRatio = sR.width()/sR.height();
    36. QRectF newRect = sR;
    37. qreal zoomLevel = 1.0;
    38. if(qAbs(lastScPos.x()-scPos.x()) > qAbs(lastScPos.y()-scPos.y())) {
    39. // width is leading the transform
    40. if(lastScPos.x() < sR.center().x()) {
    41. newRect.setLeft(scPos.x());
    42. } else if(lastScPos.x() > sR.center().x()) {
    43. newRect.setRight(scPos.x());
    44. }
    45. zoomLevel = newRect.width()/sR.width();
    46. } else {
    47. // height is leading the transform
    48. if(lastScPos.y() < sR.center().y()) {
    49. newRect.setTop(scPos.y());
    50. } else if(lastScPos.y() > sR.center().y()) {
    51. newRect.setBottom(scPos.y());
    52. }
    53. zoomLevel = newRect.height()/sR.height();
    54. }
    55. activeItem->scale(zoomLevel, zoomLevel);
    56. activeItem->setPos(activeItem->mapFromScene(newRect.topLeft()));
    57.  
    58.  
    59. } else QGraphicsScene::mouseMoveEvent(event);
    60. }
    61.  
    62. private:
    63. QGraphicsItem *activeItem;
    64. };
    65.  
    66. int main(int argc, char **argv){
    67. QApplication app(argc, argv);
    68. Scene scene;
    69. view.setScene(&scene);
    70. view.show();
    71. scene.addPixmap(QPixmap("/usr/share/wallpapers/Midnight_in_Karelia/contents/screnshot.jpg"));
    72. return app.exec();
    73. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by wysota; 14th March 2011 at 14:11.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. QGraphicsScene's sceneRect() doesn't update
    By blooglet in forum Qt Programming
    Replies: 2
    Last Post: 17th February 2011, 09:11
  2. Performance of scene(QGraphicsScene) with update();
    By mukunda in forum Qt Programming
    Replies: 4
    Last Post: 14th January 2011, 12:21
  3. Can't manually update QGraphicsScene
    By aladagemre in forum Qt Programming
    Replies: 4
    Last Post: 17th January 2010, 21:52
  4. QGraphicsScene update?
    By Gurdt in forum Qt Programming
    Replies: 11
    Last Post: 17th April 2009, 09:03
  5. Replies: 1
    Last Post: 26th December 2007, 10:58

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.