Page 2 of 2 FirstFirst 12
Results 21 to 32 of 32

Thread: Q_FOREACH deleting objects

  1. #21
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,376
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: Q_FOREACH deleting objects

    What's the point of using "c->deleteSelected()" instead of "delete c"?

    What is that you're trying to achieve? Maybe there's a better way to do it...

  2. #22
    Join Date
    Apr 2007
    Location
    Bangalore,India
    Posts
    25
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    2

    Default Re: Q_FOREACH deleting objects

    What's the point of using "c->deleteSelected()" instead of "delete c"?
    Well, I use that because before deleting c I have other stuffs to perform which I perform in deleteSelected function.

    What is that you're trying to achieve? Maybe there's a better way to do it...
    The above given example is given for clear picture about where the application crashes. The code might look stupid as I just imagined and have jot down scenario happening in my project. As I said earlier, I have some objects on drawing area and I want to delete the one which the user has selected.

    The sample below has one parent Object class with 7 children. Now I iterate over the children objects and find child2 with instance 2. If found, first I delete child2 with instance 2 and then child 3. Now my control returns to for loop, then iterate again, print "child2" with instance 3( the next child ). Finally, the last child is encountered ie child3, OH!!! but that is already deleted. but the pointer is not, hence application crashes.

    As I have been saying again and again, the same below code executes without problem on Qt3.

    I have same scenario happening in my application, it has some million lines of codes so I thought to write a sample program to reproduce the bug. And I could achieve.

    Unless the sample given below is not solved I cannot move ahead, and you know deadline I hate it but cant help.

    So, again please help me to solve the problem.
    Veda

  3. #23
    Join Date
    Feb 2006
    Posts
    157
    Qt products
    Qt3 Qt4
    Thanks
    12
    Thanked 1 Time in 1 Post

    Default Re: Q_FOREACH deleting objects

    hai


    QList<QObject*> list = obj->findChildren<QObject*>();
    for( QList<QObject*>::iterator it = list.begin(); it != list.end(); ++it )
    {
    qDebug() << (*it)->objectName();
    if( (*it)->objectName() == QString("child22") )
    {
    c31->removeChild2( c22 );
    }
    }
    I think it will again crash ,because the iterator is not aware about the “DELETION” of “C31”.
    For this we need a mechanism which will update the iterator .In Qt Assitant , it is said tat we should use “QmutableListIterator” for modifying the items in Qlist<>.

    So we have try the following code .

    Qt Code:
    1. QList< QObject* > list = obj->children();
    2. QMutableListIterator<QObject*> it(list);
    3. while( it.hasNext() )
    4. {
    5.  
    6. //qDebug() << it.next();
    7. QObject * tmpObj = it.next();
    8. qDebug() << tmpObj->objectName();
    9. if( tmpObj->objectName() == QString("child22" ) )
    10. {
    11. c31->deleteChild2( c22 );
    12. it.remove();
    13.  
    14. //list.removeAll( c31 ); //If tis line is here it works properly.
    15. // But in ourproject we cann't use this
    16. // Can i update the 'list' , just by updatin iterator.
    17.  
    18. }
    19.  
    20. }
    To copy to clipboard, switch view to plain text mode 


    Its working without crashing ( with list.removeAll( c31 ); ) . But as i mentioned , we cann't use “list.removeAll( c31)” in our project. Is there any other mechanism which will not crash or update the list ( without using list.removeAll( C31 ) ).


    thanks in advance.

  4. #24
    Join Date
    Feb 2006
    Posts
    157
    Qt products
    Qt3 Qt4
    Thanks
    12
    Thanked 1 Time in 1 Post

    Default Re: Q_FOREACH deleting objects

    Hai

    Here i have placed our code snippet . Now i can run the application without crashing. But i need a optimised code . Please help me..

    Qt Code:
    1. #include <QtGui/QApplication>
    2. #include <QDebug>
    3. #include <QList>
    4. #include <QMutableListIterator>
    5.  
    6. class parentObject : public QObject
    7. {
    8. public:
    9. parentObject( QObject* parent = 0 ) : QObject(parent){}
    10. ~parentObject(){}
    11. protected:
    12. void deleteSelected();
    13. };
    14.  
    15. class child1 : public parentObject
    16. {
    17. public:
    18. child1( QObject* parent = 0 ) : parentObject(parent){}
    19. ~child1(){}
    20. void deleteSelect()
    21. {
    22. delete this;
    23. }
    24. };
    25.  
    26. class child2 : public parentObject
    27. {
    28. public:
    29. child2( QObject* parent = 0 ) : parentObject(parent)
    30. {}
    31. ~child2(){
    32.  
    33. }
    34. void deleteSelect()
    35. {
    36. delete this;
    37. }
    38. };
    39.  
    40. class child3 : public parentObject
    41. {
    42. public:
    43. child3( QObject* parent = 0 ) : parentObject(parent){}
    44. ~child3(){}
    45. void deleteChild2( child2* c )
    46. {
    47. c->deleteSelect();
    48. delete this; //feby
    49. }
    50. /*void deleteSelect()
    51. {
    52. delete this;
    53. }*/
    54. };
    55.  
    56. int main(int argc, char *argv[])
    57. {
    58. parentObject* obj = new parentObject;
    59. child1* c11 = new child1( obj );
    60. c11->setObjectName ( "child1" );
    61. child1* c12 = new child1(obj);
    62. c12->setObjectName ( "child1" );
    63. child1* c13 = new child1(obj);
    64. c13->setObjectName ( "child1" );
    65.  
    66. child2* c21 = new child2(obj);
    67. c21->setObjectName ( "child2" );
    68. child2* c22 = new child2(obj);
    69. c22->setObjectName ( "child22" );
    70. child2* c23 = new child2(obj);
    71. c23->setObjectName ( "child2" );
    72.  
    73. child3* c31 = new child3(obj);
    74. c31->setObjectName ( "child3" );
    75.  
    76.  
    77. QList< QObject* > list = obj->children();
    78. QMutableListIterator<QObject*> it(list);
    79. while( it.hasNext() )
    80. {
    81. QObject * tmpObj = it.next();
    82. qDebug() << tmpObj->objectName();
    83. if( tmpObj->objectName() == QString("child22" ) )
    84. {
    85. c31->deleteChild2( c22 );
    86. it.remove();
    87.  
    88. list = obj->children(); // reinitialising the "list"
    89. it = list; // reinitialising the "Iterator"
    90. it.toFront(); // move the iterator the "Front" , before first item.
    91.  
    92. }
    93. }
    94.  
    95. return 0;
    96. }
    To copy to clipboard, switch view to plain text mode 

    just have a look at the code below , where i need to get it optimised.......


    Qt Code:
    1. QList< QObject* > list = obj->children();
    2. QMutableListIterator<QObject*> it(list);
    3. while( it.hasNext() )
    4. {
    5. QObject * tmpObj = it.next();
    6. qDebug() << tmpObj->objectName();
    7. if( tmpObj->objectName() == QString("child22" ) )
    8. {
    9. c31->deleteChild2( c22 );
    10. it.remove();
    11.  
    12. list = obj->children(); // reinitialising the "list"
    13. it = list; // reinitialising the "Iterator"
    14. it.toFront(); // move the iterator the "Front" , before first item.
    15.  
    16. }
    17. }
    To copy to clipboard, switch view to plain text mode 


    here after deleteChild2(), i am reinitialising the list, iterator. But it is not feasible( same thime it's not crashing ). Because if we want to call deleteChild2() , more times say 100. this iterating process will be killing overhead. So i want to optimise this code any how.

    Can anybody help me out to resolve this ..??
    Thanks

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

    Default Re: Q_FOREACH deleting objects

    Quote Originally Posted by veda View Post
    Well, I use that because before deleting c I have other stuffs to perform which I perform in deleteSelected function.
    Why not put it into the class destructor? That's what it is for, isn't it?


    The above given example is given for clear picture about where the application crashes. The code might look stupid as I just imagined and have jot down scenario happening in my project. As I said earlier, I have some objects on drawing area and I want to delete the one which the user has selected.
    So why not keep a pointer directly to this object instead of searching for it in the list of all children?


    The sample below has one parent Object class with 7 children. Now I iterate over the children objects and find child2 with instance 2. If found, first I delete child2 with instance 2 and then child 3. Now my control returns to for loop, then iterate again, print "child2" with instance 3( the next child ). Finally, the last child is encountered ie child3, OH!!! but that is already deleted. but the pointer is not, hence application crashes.
    Do a recursion over the tree instead of using a flat list.


    here after deleteChild2(), i am reinitialising the list, iterator.
    This is not an option.

    Why are you getting a list of all children instead of directly accessing the items you want from a particular subtree of objects? Iterating the list of all children is an overkill as well, as you can probably skip 90% of objects that you know upfront you won't need to check.

  6. #26
    Join Date
    Apr 2007
    Location
    Bangalore,India
    Posts
    25
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    2

    Default Re: Q_FOREACH deleting objects

    Why not put it into the class destructor? That's what it is for, isn't it?
    Yes I do exactly that. Something like this
    Qt Code:
    1. void class: deleteSelected()
    2. {
    3. if( isSelected )
    4. delete this; // calls the destructor
    5. }
    6. class::~class()
    7. {
    8. //do other stuffs like unselecting and then setting some properties
    9. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. So why not keep a pointer directly to this object instead of searching for it in the list of all children?
    To copy to clipboard, switch view to plain text mode 
    Because there can be any number of objects and I dont know in advance which object the user has selected at run time, so I need to iterate through the list and see which object is selected and delete accordingly. There can be any number selected 1, 2, 3 etc objects. So I dont I can keep a pointer directly to this object.

    Do a recursion over the tree instead of using a flat list.
    Can you tell me how...

    Isnt there any solution in the sample program that I have provided above???? Cannot I delete the pointer too in the above scenario....

    wysota, please throw some light on above given solution as how joseph lightens...

    Thanks....
    Veda

  7. #27
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,376
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: Q_FOREACH deleting objects

    Quote Originally Posted by veda View Post
    Yes I do exactly that. Something like this
    Qt Code:
    1. void class: deleteSelected()
    2. {
    3. if( isSelected )
    4. delete this; // calls the destructor
    5. }
    6. class::~class()
    7. {
    8. //do other stuffs like unselecting and then setting some properties
    9. }
    To copy to clipboard, switch view to plain text mode 
    What's the point of checking it for selected if you don't know if it is selected (as you mention below)?

    Because there can be any number of objects
    So keep a list.
    and I dont know in advance which object the user has selected at run time,
    How come? The selection is made probably by clicking or choosing something so you can connect to the appropriate signal and add/remove the object from your list.

    There can be any number selected 1, 2, 3 etc objects. So I dont I can keep a pointer directly to this object.
    I suggest you do it. You'll solve many issues this way.

    Can you tell me how...
    More or less like this:
    Qt Code:
    1. void deleteChild(QObject *o, const QString &type){
    2. if(type = o->metaObject()->className())
    3. delete o;
    4. else
    5. foreach(QObject *child, o->children()){
    6. deleteChild(child, type);
    7. }
    8. }
    To copy to clipboard, switch view to plain text mode 
    Then call this method on the top level object. It'll iterate all children and delete every one of them that is of type "type" (and all its children). It should work quite fast because it doesn't do any unnecessary checks on child object if it discovers that a parent object is to be deleted.

  8. The following user says thank you to wysota for this useful post:

    veda (22nd May 2007)

  9. #28
    freeskydiver Guest

    Default Re: Q_FOREACH deleting objects

    Why not so? You go backward ...and you can kill the object anytime.
    Qt Code:
    1. QList< QObject* > list = obj->children();
    2. QMutableListIterator<QObject*> it(list);
    3. it.toBack();
    4. while( it.hasPrevious() )
    5. {
    6. QObject * tmpObj = it.previous();
    7. qDebug() << tmpObj->objectName();
    8. if( tmpObj->objectName() == QString("child22" ) )
    9. {
    10. c31->deleteChild2( c22 );
    11. it.remove();
    12. }
    13. }
    To copy to clipboard, switch view to plain text mode 

  10. #29
    Join Date
    Apr 2007
    Location
    Bangalore,India
    Posts
    25
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    2

    Default Re: Q_FOREACH deleting objects

    Wow!!!

    I'm just jumping...Too happy....Great.

    Thanks a lot and also to help me in optimizing my code....

    Here is the working code. Any comments
    Old code
    Qt Code:
    1. QObjectList *list;
    2. QListIterator<QObject*> *it;
    3.  
    4. QObject *obj;
    5. list = new QObjectList( children() );
    6. if( list->count() != 0 )
    7. {
    8. it = new QListIterator<QObject*>( *list );
    9. while ( it->hasNext() )
    10. {
    11. obj = it->next();
    12. if( obj->isA( "myObject" ) )
    13. ((myObject *)obj)->deleteSelected();
    14. }
    15. delete it;
    16. }
    17. delete list;
    To copy to clipboard, switch view to plain text mode 

    New code
    Qt Code:
    1. for(; it!=list.end(); ++it)
    2. {
    3. if( ((myobject *)(*it))->isSelected() )
    4. selectedList.append( *it );
    5. }
    6. Q_FOREACH( QObject* obj, selectedList )
    7. {
    8. ((myobject*)obj)->deleteSelected();
    9. }
    To copy to clipboard, switch view to plain text mode 
    Veda

  11. #30
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,376
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: Q_FOREACH deleting objects

    Quote Originally Posted by freeskydiver View Post
    Why not so? You go backward ...and you can kill the object anytime.
    It may fail if the order of objects in the list is that a child is before a parent in the list. Qt docs don't say anything about the order, so it's risky.

    Veda: Your new code doesn't seem complete. And what's the point of having two loops that do the same?

  12. #31
    freeskydiver Guest

    Default Re: Q_FOREACH deleting objects

    Quote Originally Posted by wysota View Post
    It may fail if the order of objects in the list is that a child is before a parent in the list.
    Ok.. that's right. When you have dependent objects in your list.
    Quote Originally Posted by wysota View Post
    Qt docs don't say anything about the order, so it's risky.
    Really? Actually Qt change the list sequence only after the point of last deleting, or?

  13. #32
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,376
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    Wiki edits
    10

    Default Re: Q_FOREACH deleting objects

    Quote Originally Posted by freeskydiver View Post
    Ok.. that's right. When you have dependent objects in your list.
    That's the reason why the original code crashed in the first place.

    Really? Actually Qt change the list sequence only after the point of last deleting, or?
    Quote Originally Posted by QObject docs:
    Note that the list order changes when QWidget children are raised or lowered. A widget that is raised becomes the last object in the list, and a widget that is lowered becomes the first object in the list.
    So as you see the order is in general undefined. At least I wouldn't count on it being defined

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
  •  
Qt is a trademark of The Qt Company.