Results 1 to 13 of 13

Thread: When is the best time to delete a QCanvasItem

  1. #1
    Join Date
    Feb 2006
    Posts
    14
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default When is the best time to delete a QCanvasItem

    Hi

    Using Qt3.3.3.

    This may seem a bizzare question but hear me out. I have a derived QCanvas class which has derived QCanvasItems (QCanvasRectangleItems) in/on it. The canvas items are parented to this derived QCanvas.

    I use the delete on an instance of a QCanvasItem to remove it from the canvas. Inside the destructor of the derived QCanvasItem I call hide().

    However peridically when I have delete a derived QCanvasItem, a tiny bit later a fatal crash has occurred in either QCanvasItemList::drawUnique( QPainter& painter ) try in access a duff QCanvasItem pointer, or QCanvas::collisions when itereating through its list of items, or in QCanvas::update().

    So should I be doing anything else to ensure a QCanvasItem is removed from the QCanvas internal list(s)?

    Thanks
    Cya Illya

  2. #2
    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: When is the best time to delete a QCanvasItem

    No, deleting the item is enough to remove it from all QCanvas data structures. If you experience a crash, it must be because of your own datastructures, probably some invalid pointer or something. Can we see some code you expect to be erroneus?

  3. #3
    Join Date
    Feb 2006
    Posts
    14
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: When is the best time to delete a QCanvasItem

    Hi

    I have managed to make the crash more regular now. The scenerio is as follows:
    I delete a group of items. I then need to detect when my mouse is over another item by calling collisions(); Collisions tried to iterate through a list of visible items from its chunks.
    It is crashing when it tries to reference an item from this list.

    I also get a situation where being fast with the mouse I move a groups of widgets over the area of the canvas which previous had items there but just been deleted. Again iterating items from Qt chunks.

    It will also crash in QCanvas::update() when using QCanvasItem::drawUnique() again when a little earlier in the call stack retrived a list of items from chunks() to reference. This may either be from my code or when the QCanvasView performs an update straight from Qt code (none of my functions are called in the call stack)

    It seems the QCanvas chunks and/or the chunks held by each item is out of date.

    I have to be sure its not my remaining items iterated through allItems() and tested each item is valid just prior to an update() or collision() on the theory if I had access to a bad item so would QCanvas. My const QCanvasItemList lista = allItems() of items are all fine.

    In summary I delete some widgets. Then Qt may on a call to collision() or update() which iterates a list of items retrieved from chunks crash accessing an item pointer. Lines 13 and 14.

    Qt Code:
    1. QCanvasItemList QCanvas::collisions(const QPointArray& chunklist,
    2. const QCanvasItem* item, bool exact) const
    3. {
    4. QPtrDict<void> seen;
    5. QCanvasItemList result;
    6. for (int i=0; i<(int)chunklist.count(); i++) {
    7. int x = chunklist[i].x();
    8. int y = chunklist[i].y();
    9. if ( validChunk(x,y) ) {
    10. const QCanvasItemList* l = chunk(x,y).listPtr();
    11. for (QCanvasItemList::ConstIterator it=l->begin(); it!=l->end(); ++it) {
    12. QCanvasItem *g=*it;
    13. if ( g != item ) {
    14. if ( !seen.find(g) ) {
    15. seen.replace(g,(void*)1);
    16. if ( !exact || item->collidesWith(g) )
    17. result.append(g);
    18. }
    19. }
    20. }
    21. }
    22. }
    23. return result;
    24. }
    To copy to clipboard, switch view to plain text mode 

  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: When is the best time to delete a QCanvasItem

    Do you use multiple threads in your application? Could we see some of your code?

  5. #5
    Join Date
    Feb 2006
    Posts
    14
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: When is the best time to delete a QCanvasItem

    Hi

    No the code is not multithreaded. In brief an explanation of the order code called
    1. A BGraphWgtBase_c (QCanvasItem) is deleted
    2. It marks itself for deletion.
    3. Qt passes overridden mouse type calls to my code; press, release and move
    4. The canvas deletes marked items
    5. My code then carries out the wishes of the uses for that pass.
    6. My code test for item collisions with the mouse
    7. Some canvas updates may take place.
    8. A crash may occur now.
    9. Mean while there is a canvas timer to update peridocially any items that have flaged to be updated.

    Qt Code:
    1. BGraphWgtBase_c::~BGraphWgtBase_c( void )
    2. {
    3. hide();
    4. DeleteChildren();
    5. }
    6.  
    7. //virtual
    8. bool BGraphWgtBase_c::Redraw()
    9. {
    10. QRect rectToRefresh( boundingRect() );
    11. m_pParent->setChanged( rectToRefresh );
    12. m_pParent->SetDoARedrawPlease();
    13.  
    14. return RDstatus::success;
    15. }
    16.  
    17. bool BGraphWgtBase_c::SetMarkForDelete()
    18. {
    19. m_bIsMarkedForDelete = true;
    20. hide();
    21.  
    22. // Now go through all this widget's child widgets and mark for delete too
    23. ListWgts::iterator it = m_listChildWidgets.begin();
    24. while( it != m_listChildWidgets.end() )
    25. {
    26. BGraphWgtBase_c * pWgt = *it;
    27. if( pWgt == NULL )
    28. {
    29. continue;
    30. }
    31. pWgt->hide();
    32. pWgt->SetMarkForDelete();
    33.  
    34. // Move to next
    35. ++it;
    36. }
    37.  
    38. return RDstatus::success;
    39. }
    40. // Slot
    41. // Visited every 500ms to do canvas updates
    42. void BGraphCanvas_c::SlotUpdateTimer()
    43. {
    44. if( m_bDoARedrawPlease )
    45. {
    46. m_bDoARedrawPlease = false;
    47.  
    48. try
    49. {
    50. update();
    51. }
    52. catch( ... )
    53. {
    54.  
    55. }
    56. }
    57.  
    58. return;
    59. }
    60.  
    61. // Set by BGraphWgtBase_c to flag that at least one item on the canvas
    62. // would like to be updated
    63. bool BGraphCanvas_c::SetDoARedrawPlease()
    64. {
    65. m_bDoARedrawPlease = true;
    66. return RDstatus::success;
    67. }
    68.  
    69. // This function goes through all the widgets ( canvas items ) registered with this canvas
    70. // and deletes the items which have been marked for deletion. Widgets for this canvas class
    71. // operation do not get deleted at source when not needed as they may be still in use, or their
    72. // children still in use. They could be contained in the canvas's various containers at the
    73. // time they are deemed as not needed anymore. This function and the
    74. // BGraphWgtBase_c::SetMarkForDelete function enacts a delayed delete system. At the
    75. // source hide the widget and mark for delete. This function is called sometime later and will delete the
    76. // marked items. BGraphWgtBase_c::SetMarkForDelete function also at the same time informs the BGraphWgtMgr_c
    77. // of the widget's removal so it can update its records.
    78. // Note: Very important when this is called. For example do not call at end of
    79. // mouseReleaseEvent(). QCanvas does behind the scenes work
    80. // on all it canvas items after mouseReleaseEvent() and so deleting any before then
    81. // is not a good and causes a crash.
    82. bool BGraphCanvas_c::DeleteMarkedWgts()
    83. {
    84. BGraphWgtBase_c * pCurrentSelectedWgt = GetView()->GetCurrentSelectedItem();
    85. bool bDeleteWgt = false;
    86. QCanvasItemList listAllItems = allItems();
    87. QCanvasItemList::iterator it = listAllItems.begin();
    88. while( it != listAllItems.end() )
    89. {
    90. BGraphWgtBase_c * pWgt = dynamic_cast< BGraphWgtBase_c * >( *it );
    91. if( (pWgt != NULL) && pWgt->IsMarkForDelete() )
    92. {
    93. if( pWgt == pCurrentSelectedWgt )
    94. {
    95. GetView()->SetCurrentSelectedItem( NULL );
    96. }
    97.  
    98. delete pWgt;
    99. bDeleteWgt = true;
    100. }
    101.  
    102. // Next
    103. ++it;
    104. }
    105.  
    106. if( bDeleteWgt )
    107. {
    108. update();
    109. }
    110.  
    111. return RDstatus::success;
    112. }
    113.  
    114. QCanvasItemList BGraphCanvas_c::GetDlgsHitHoverOver( const QPoint & vMousePos )
    115. {
    116. QCanvasItemList wgtHoverOverHitList;
    117. QPoint realMousePos( GetRealX( vMousePos.x() ), GetRealY( vMousePos.y() ) );
    118. wgtHoverOverHitList = Collisions( realMousePos );
    119.  
    120. return wgtHoverOverHitList;
    121. }
    122.  
    123. //virtual
    124. void BGraphCanvas_c::update()
    125. {
    126. // The try catch is here to stop QCanvas crash if it comes
    127. // across an invalid pointer to a QCanvasItem. This is a bug which
    128. // has been difficult to solve as when is the right time to delete
    129. // a QCanvasItem. See DeleteWgts() in this class which is there to
    130. // try to stop this sort of thing happening.
    131. try
    132. {
    133. QCanvas::update();
    134. }
    135. catch( ... )
    136. {
    137. ;
    138. }
    139. }
    140.  
    141. QCanvasItemList BGraphCanvas_c::Collisions( const QPoint & vMousePos )
    142. {
    143. try
    144. {
    145. return collisions( vMousePos );
    146. }
    147. catch( ... )
    148. {
    149. ;
    150. }
    151.  
    152. QCanvasItemList list;
    153. return list;
    154. }
    155.  
    156. // vpWgtExceptThisOne would normally be the current selected widget
    157. const RDstr BGraphCanvas_c::GetDlgHitHoverOver( const QPoint & vMousePos, BGraphWgtBase_c * vpWgtExceptThisOne )
    158. {
    159. RDstr dlgId;
    160.  
    161. if( !IsOnCanvas( vMousePos ) )
    162. {
    163. return dlgId;
    164. }
    165.  
    166. QPoint realMousePos( GetRealX( vMousePos.x() ), GetRealY( vMousePos.y() ) );
    167. QCanvasItemList listDlgHitByMouse = Collisions( realMousePos );
    168.  
    169. // User clicked on a widget that recognised itself as hitable/selectable
    170. dlgId = pDlgItem->GetId();
    171.  
    172. return dlgId;
    173. }
    174.  
    175. // return: valid id or no id = no hit
    176. const RDstr BGraphCanvas_c::GetDlgHit( const QPoint & vMousePos, BGraphWgtBase_c * vpWgtExceptThisOne )
    177. {
    178. return GetDlgHitHoverOver( vMousePos, vpWgtExceptThisOne );
    179. }
    180.  
    181.  
    182.  
    183. bool BGraphCanvas_c::IsThisWidgetHit( const QPoint & vPosMouse, const RDstr & vWidgetId )
    184. {
    185. bool bHaveHitSpecificWidget = false;
    186.  
    187. QCanvasItemList listHitItems = GetDlgsHitHoverOver( vPosMouse );
    188.  
    189. return bHaveHitSpecificWidget;
    190. }
    191.  
    192. void BGraphCanvasView_c::mousePressEvent( QMouseEvent * vpEvent )
    193. {
    194. // Clean out widgets marked for deletion. Very important this is called here
    195. // and not say on mouseReleaseEvent(). QCanvas does behind the scenes work
    196. // on all it canvas items after mouseReleaseEvent() and so deleting any before then
    197. // is not a good and causes a crash.
    198. m_pGraphAreaCanvas->DeleteMarkedWgts();
    199.  
    200. // Has user clicked on an canvas area dialog (QCanvasItem )
    201. m_mouseButtonPressCursorPos = viewportToContents( vpEvent->pos() );
    202.  
    203. m_currentSelectedAreaDlgId = m_pGraphAreaCanvas->GetDlgHit( m_mouseButtonPressCursorPos, NULL );
    204. m_pCurrentSelectedWgt = m_pGraphAreaCanvas->GetDlgObj( m_currentSelectedAreaDlgId );
    205. if( NULL == m_pCurrentSelectedWgt )
    206. {
    207. // Reset all widget depths accept the current selected widget
    208. m_pAGraph->GetGraphCanvasWgtMgr()->WgtsSetAllToNominalAreaZDepth( NULL );
    209. return;
    210. }
    211.  
    212. // Create store for event into to be passed onto all hit widgets (canvas items)
    213. BGraphWgtEventInfo_s sEventInfo;
    214.  
    215. // Pass event onto selected widget (canvas item)
    216. if( m_pCurrentSelectedWgt->MousePressEvent( sEventInfo ) )
    217. {
    218. // Inform the client using BPkgGraph that possible item valid for selection is selected
    219. m_pAGraph->SetCurrentlySelectedWidgetId( m_pCurrentSelectedWgt->GetId() );
    220. }
    221.  
    222. // Pass event onto rest of hit widgets. These are not the most forward Z pos
    223. // widgets.
    224. m_pGraphAreaCanvas->MousePressEvent( sEventInfo );
    225.  
    226. // Reset all widget depths accept the current selected widget
    227. m_pAGraph->GetGraphCanvasWgtMgr()->WgtsSetAllToNominalAreaZDepth( m_pCurrentSelectedWgt );
    228. }
    229.  
    230. void BGraphCanvasView_c::mouseReleaseEvent( QMouseEvent * vpEvent )
    231. {
    232. // Create store for event into to be passed onto all hit widgets (canvas items)
    233.  
    234. if( NULL != m_pCurrentSelectedWgt )
    235. {
    236. // Pass event onto selected widget (canvas item)
    237. m_pCurrentSelectedWgt->MouseReleaseEvent( sEventInfo );
    238. }
    239.  
    240. // Pass event onto rest of hit widgets. These are not the most forward Z pos
    241. // widgets.
    242. m_pGraphAreaCanvas->MouseReleaseEvent( sEventInfo );
    243.  
    244. // Reset all widget depths accept the last selected widget
    245. m_pAGraph->GetGraphCanvasWgtMgr()->WgtsSetAllToNominalAreaZDepth( m_pCurrentSelectedWgt );
    246. }
    247.  
    248.  
    249. void BGraphCanvasView_c::contentsMouseMoveEvent( QMouseEvent * vpEvent )
    250. {
    251. // Create store for event into to be passed onto all hit widgets (canvas items)
    252.  
    253. // User clicked on an canvas area dialog (QCanvasItem )
    254. if( m_bMouseLeftButtonHitAreaDlg && m_bMouseLeftButtonDown )
    255. {
    256. // to use this m_currentSelectedAreaDlgId
    257. if( NULL != m_pCurrentSelectedWgt )
    258. {
    259. // Pass event onto selected widget (canvas item)
    260. m_pCurrentSelectedWgt->MouseContentMoveEvent( sEventInfo );
    261. }
    262. }
    263.  
    264. // Pass event onto rest of hit widgets. These are not the most forward Z pos
    265. // widgets.
    266. m_pGraphAreaCanvas->MouseContentMoveEvent( sEventInfo );
    267.  
    268. // User just moving the mouse over the canvas. Highlight most forward hit widget if any.
    269. // Unhighlight previous widget if it still exists
    270. // Turn off all/any highlighted hit widget areas
    271. QPoint mousePos( vpEvent->pos() );
    272. const RDstr wgtId = m_pGraphAreaCanvas->GetDlgHitHoverOver( mousePos, pWgtExceptThisOne );
    273.  
    274. // Crash in collisions in GetDlgHitHoverOver()
    275. // snip
    276. }
    277. }
    278.  
    279. // Update the view
    280. m_pGraphAreaCanvas->update();
    281. }
    To copy to clipboard, switch view to plain text mode 

  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: When is the best time to delete a QCanvasItem

    Note that canvas items are not widgets.

    Your code is quite complex -- it uses many variables and methods. Could you post a minimal compilable example which reproduces the problem?

  7. #7
    Join Date
    Jan 2006
    Location
    Athens - Greece
    Posts
    219
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: When is the best time to delete a QCanvasItem

    Or post a debugger backtrace to lead us somewhere...
    Anyway I'd also delete the item like:
    Qt Code:
    1. delete pWgt;
    2. pWgt = NULL;
    To copy to clipboard, switch view to plain text mode 
    I have the feeling that the qt "internals" would check for null pointers before using them (I know I do)

  8. #8
    Join Date
    Feb 2006
    Posts
    14
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: When is the best time to delete a QCanvasItem

    Hi

    On Linux a can get the following back trace:

    Program received signal SIGSEGV, Segmentation fault.
    [Switching to Thread -150104960 (LWP 3629)]
    0xc31600d2 in ?? ()
    (gdb) bt
    #0 0xc31600d2 in ?? ()
    #1 0x0b0af5dd in ?? ()
    #2 0x00bde85d in QCanvasItemList::drawUnique (this=0xfee4a090,
    painter=@0xfee49f20) at canvas/qcanvas.cpp:349
    #3 0x00be25a2 in QCanvas::drawCanvasArea (this=0xafd1b00, inarea=@0xfee4a120,
    p=0x0, double_buffer=true) at canvas/qcanvas.cpp:1431
    #4 0x00be1f00 in QCanvas::drawChanges (this=0xafd1b00, inarea=@0xb10dac8)
    at canvas/qcanvas.cpp:1337
    #5 0x00be1516 in QCanvas::update (this=0xafd1b00) at canvas/qcanvas.cpp:1183
    #6 0x082dbd6b in BGraphCanvasView_c::contentsMouseMoveEvent (this=0xafd1ec0,
    vpEvent=0xfee4a510) at BPkgGraph/BGraphCanvasView.cpp:999
    #7 0x00ac629d in QScrollView::viewportMouseMoveEvent (this=0xafd1ec0,
    e=0xfee4a8a0) at widgets/qscrollview.cpp:1782
    #8 0x00ac5756 in QScrollView::eventFilter (this=0xafd1ec0, obj=0xa8144b0,
    e=0xfee4a8a0) at widgets/qscrollview.cpp:1512
    #9 0x00975967 in QObject::activate_filters (this=0xa8144b0, e=0xfee4a8a0)
    at kernel/qobject.cpp:902
    #10 0x009757d8 in QObject::event (this=0xa8144b0, e=0xfee4a8a0)
    at kernel/qobject.cpp:735
    #11 0x009bbca6 in QWidget::event (this=0xa8144b0, e=0xfee4a8a0)
    at kernel/qwidget.cpp:4655
    #12 0x0090a6f5 in QApplication::internalNotify (this=0xfee4ad70,
    receiver=0xa8144b0, e=0xfee4a8a0) at kernel/qapplication.cpp:2635
    #13 0x00909dff in QApplication::notify (this=0xfee4ad70, receiver=0xa8144b0,
    e=0xfee4a8a0) at kernel/qapplication.cpp:2421
    #14 0x00892f05 in QApplication::sendSpontaneousEvent (receiver=0xa8144b0,
    event=0xfee4a8a0) at qapplication.h:494
    #15 0x0088b3d8 in QETWidget::translateMouseEvent (this=0xa8144b0, event=0xfee4ac30)
    at kernel/qapplication_x11.cpp:4288
    #16 0x00888cd3 in QApplication::x11ProcessEvent (this=0xfee4ad70, event=0xfee4ac30)
    at kernel/qapplication_x11.cpp:3439
    ---Type <return> to continue, or q <return> to quit---
    #17 0x008a5e84 in QEventLoop:rocessEvents (this=0xa5d6ce0, flags=4)
    at kernel/qeventloop_x11.cpp:192
    #18 0x0091f234 in QEventLoop::enterLoop (this=0xa5d6ce0)
    at kernel/qeventloop.cpp:198
    #19 0x0091f150 in QEventLoop::exec (this=0xa5d6ce0) at kernel/qeventloop.cpp:145
    #20 0x0090a8a7 in QApplication::exec (this=0xfee4ad70)
    at kernel/qapplication.cpp:2758
    #21 0x0808ae0a in main (argc=1, argv=0xfee4aee4) at BCommon/main.cpp:148

    and

    (gdb) r
    Starting program: /cygdrive/c/_devroot/SCE/pootle/branches/RDdev_PSSGTool/BarleyMow/PSSGToolDllD.exe

    Program received signal SIGSEGV, Segmentation fault.
    0x39f8e02d in qt-mt333!?collidesWith@QCanvasRectangle@@UBE_NPBVQCanvasItem@@@Z
    () from /cygdrive/c/Qt/3.3.3/bin/qt-mt333.dll
    (gdb) bt
    #0 0x39f8e02d in qt-mt333!?collidesWith@QCanvasRectangle@@UBE_NPBVQCan vasItem@@@Z () from /cygdrive/c/Qt/3.3.3/bin/qt-mt333.dll
    #1 0x39f8e442 in qt-mt333!?collisions@QCanvas@@QBE?AVQCanvasItemList@@ ABVQPointArray@@PBVQCanvasItem@@_N@Z () from /cygdrive/c/Qt/3.3.3/bin/qt-mt333.dll
    #2 0x39f8e1c3 in qt-mt333!?collisions@QCanvasItem@@QBE?AVQCanvasItemLi st@@_N@Z () from /cygdrive/c/Qt/3.3.3/bin/qt-mt333.dll
    #3 0x39f8e2aa in qt-mt333!?collisions@QCanvas@@QBE?AVQCanvasItemList@@ ABVQRect@@@Z () from /cygdrive/c/Qt/3.3.3/bin/qt-mt333.dll
    #4 0x39f8e226 in qt-mt333!?collisions@QCanvas@@QBE?AVQCanvasItemList@@ ABVQPoint@@@Z () from /cygdrive/c/Qt/3.3.3/bin/qt-mt333.dll
    #5 0x0091dabe in PSSGToolDllD!?GetClassStr@BExcepWkBuild_CreateWkCr iteriaFailure_c@@SA?AVRDstr@@XZ ()
    #6 0x0091dfc2 in PSSGToolDllD!?GetClassStr@BExcepWkBuild_CreateWkCr iteriaFailure_c@@SA?AVRDstr@@XZ ()
    #7 0x009235a2 in PSSGToolDllD!?GetClassStr@BExcepWkBuild_CreateWkCr iteriaFailure_c@@SA?AVRDstr@@XZ ()
    #8 0x39df0a55 in qt-mt333!?event@QWidget@@MAE_NPAVQEvent@@@Z ()
    from /cygdrive/c/Qt/3.3.3/bin/qt-mt333.dll
    #9 0x39d509c8 in qt-mt333!?internalNotify@QApplication@@AAE_NPAVQObjec t@@PAVQEvent@@@Z () from /cygdrive/c/Qt/3.3.3/bin/qt-mt333.dll
    #10 0x39d5023a in qt-mt333!?notify@QApplication@@UAE_NPAVQObject@@PAVQE vent@@@Z () from /cygdrive/c/Qt/3.3.3/bin/qt-mt333.dll
    #11 0x39d0e4eb in qt-mt333!?sendSpontaneousEvent@QApplication@@CA_NPAVQ Object@@PAVQEvent@@@Z () from /cygdrive/c/Qt/3.3.3/bin/qt-mt333.dll
    #12 0x39d0889e in qt-mt333!?winMouseButtonUp@QApplication@@SAXXZ ()
    from /cygdrive/c/Qt/3.3.3/bin/qt-mt333.dll
    #13 0x39d05e2e in qt-mt333!?winFocus@QApplication@@QAEXPAVQWidget@@_N@Z ()
    from /cygdrive/c/Qt/3.3.3/bin/qt-mt333.dll
    #14 0x77d48734 in USER32!GetDC () from /cygdrive/c/WINDOWS/system32/user32.dll
    #15 0x00060a5a in ?? ()
    #16 0x00000201 in ?? ()
    #17 0x00000001 in ?? ()
    #18 0x01900069 in ?? ()
    #19 0x39d05880 in qt-mt333!?winFocus@QApplication@@QAEXPAVQWidget@@_N@Z ()
    from /cygdrive/c/Qt/3.3.3/bin/qt-mt333.dll
    #20 0x77d48816 in USER32!GetDC () from /cygdrive/c/WINDOWS/system32/user32.dll
    #21 0x39d05880 in qt-mt333!?winFocus@QApplication@@QAEXPAVQWidget@@_N@Z ()
    from /cygdrive/c/Qt/3.3.3/bin/qt-mt333.dll
    #22 0x77d489cd in USER32!GetWindowLongW ()
    from /cygdrive/c/WINDOWS/system32/user32.dll
    #23 0x00000000 in ?? () from
    (gdb) quit

    Both of these traces show 2 of the 3 possible crash sites. I do not know which it will be till iit happens. The collisions trace above would be called from BGraphCanvas::GetDlgHitHoverOver() function.

    Cya Illya

  9. #9
    Join Date
    Feb 2006
    Posts
    14
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: When is the best time to delete a QCanvasItem - example code

    Hi

    I have just created a example project that reproduces the the crashes I get. It is a VC++ project in the .zip file.
    Unzip and build the project. It builds against Qt3.3.3.

    Run the example. Click in the QCanvasView whitespace to bring up a context menu to add some QCanvasItems (set of 4 at a time) to the canvas. Add a few. Then select a QCanvasItem to bring up a context menu item to delete it and the rest of the set. Move the other items around. Add a new item. Delete another. Move/select. Continue until there is a crash.

    Let me know how you get on.

    Cya Illya
    Attached Files Attached Files

  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: When is the best time to delete a QCanvasItem

    I get lots or warnings and in the end, a linking error (undefined vtable for BGraphCanvasView_c). Maybe you should correct those before continuing? And a working .pro file would be nice, too, not everybody uses M$ VS.

  11. #11
    Join Date
    Feb 2006
    Posts
    14
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: When is the best time to delete a QCanvasItem

    Hi
    Please find .pro file content for the files in the .zip above.
    This has been tested and compiles though with float to int warnings and runs.
    Cya Illya

    # ----------------------------------------------------------
    # Project generated by QMsNet v1.0.0
    # Template used: Basic Application
    # Template version: 1.1
    # ----------------------------------------------------------

    TEMPLATE = app
    TARGET = QCanvasCrashTest
    LANGUAGE = C++
    CONFIG += qt warn_on stl exceptions rtti


    UI_DIR = ui
    MOC_DIR = output
    OBJECTS_DIR = output
    DESTDIR = .

    INCLUDES += .

    SOURCES += main.cpp
    SOURCES += BGraphCanvas.cpp
    SOURCES += BGraphCanvasView.cpp
    SOURCES += BGraphWgtBase.cpp
    SOURCES += BGraphWgtDialog.cpp

    HEADERS += BGraphCanvas.h
    HEADERS += BGraphCanvasView.h
    HEADERS += BGraphWgtBase.h
    HEADERS += BGraphWgtDialog.h
    Last edited by irudkin; 15th February 2006 at 16:58. Reason: no attachment can be added with .pro extentsion

  12. #12
    Join Date
    Feb 2006
    Posts
    14
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: When is the best time to delete a QCanvasItem

    Hi

    It has been fixed. Horray. A nice chap at Qt support saw the problem and luckily my example had made the problem worst. Anyway here it is:

    // Note: if you reimplement the boundingRect() function
    //of your QCanvasRectangle subclass and change the values this function
    //returns while the item is visible, sure to call QCanvasPolygonalItem::invalidate().
    // If you do not the QCanvas will use one bounding rectangle when adding the
    // item to the chunks and a different one
    //when removing, causing the internal list of items to still contain your
    //item after it has been hidden. When the item is deleted, QCanvas still
    //believes that the item is visible and uses the pointer and thus your
    //program crashes. You will need to call
    //invalidate() on the item if you do change it.

    I did not realise from the Qt documentation overriding the boundRect() and changing the size would have this effect.

    Cya Illya

  13. #13

    Default Re: When is the best time to delete a QCanvasItem

    Quote Originally Posted by irudkin View Post
    Hi

    It has been fixed. Horray. A nice chap at Qt support saw the problem and luckily my example had made the problem worst. Anyway here it is:

    // Note: if you reimplement the boundingRect() function
    //of your QCanvasRectangle subclass and change the values this function
    //returns while the item is visible, sure to call QCanvasPolygonalItem::invalidate().
    // If you do not the QCanvas will use one bounding rectangle when adding the
    // item to the chunks and a different one
    //when removing, causing the internal list of items to still contain your
    //item after it has been hidden. When the item is deleted, QCanvas still
    //believes that the item is visible and uses the pointer and thus your
    //program crashes. You will need to call
    //invalidate() on the item if you do change it.

    I did not realise from the Qt documentation overriding the boundRect() and changing the size would have this effect.

    Cya Illya
    I have seen the same problems about removing properly the QCanvasItem from the QCanvas. But I did not see the satisfying answer.

    I have faced with the same problem. After two days, we found and solved the result as in the following.

    When we try to delete the any items from the QCanvas by using the delete statement, we are facing the problem with resize or some thing like that which causes to call the update function of the QCanvas. In detail, it call the drawUnique() function. Anyway, althoug we delete the QCanvasItem from QCanvas, it stores another list which is a memeber of QCanvasChunk. That is, QCanvas uses another list in order to improve the its performance. It uses chunks which displays the changed items in the QCanvas. Therfore, we have to clear this list as well.

    In order to do that, First, we can put setVisible(false) or hide() or invalidate() functions at the begining of the overloaded areaPoints() function. Then, we can add setVisible(true) or show() or update() functions at the end of the areaPoints() function.


    setVisible() (or the others listed above) call to removeFromChunks() or addChunks() function. So any action which causes to call update function can not reason any conflists between the removed QCanvasItems and the internal list ( the list member of QCanvasChunk ) .

    I think it should be a function of QCanvas which clear the chunks as well and it should be used in the destructor like hide as documented.

    Best regards
    Serhat
    Last edited by ksbaydar; 8th March 2007 at 23:07.

Similar Threads

  1. Replies: 4
    Last Post: 19th February 2009, 12:10
  2. How to constantly refresh time on a view
    By salmanmanekia in forum Qt Programming
    Replies: 5
    Last Post: 23rd June 2008, 13:44
  3. QDateTime GMT add sec. or - sec. from locale time....
    By patrik08 in forum Qt Programming
    Replies: 2
    Last Post: 20th February 2007, 17:39
  4. c++, placement delete upon exception
    By stinos in forum General Programming
    Replies: 6
    Last Post: 31st October 2006, 16:38
  5. Problem with pointers while using localtime() and time()
    By jamadagni in forum General Programming
    Replies: 7
    Last Post: 11th January 2006, 16:48

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.