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...
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...
Well, I use that because before deleting c I have other stuffs to perform which I perform in deleteSelected function.What's the point of using "c->deleteSelected()" instead of "delete c"?
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.What is that you're trying to achieve? Maybe there's a better way to do it...
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 deadlineI hate it but cant help.
So, again please help me to solve the problem.![]()
Veda
hai
I think it will again crash ,because the iterator is not aware about the “DELETION†of “C31â€.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 );
}
}
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:
QMutableListIterator<QObject*> it(list); while( it.hasNext() ) { //qDebug() << it.next(); qDebug() << tmpObj->objectName(); { c31->deleteChild2( c22 ); it.remove(); //list.removeAll( c31 ); //If tis line is here it works properly. // But in ourproject we cann't use this // Can i update the 'list' , just by updatin iterator. } }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.
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:
#include <QtGui/QApplication> #include <QDebug> #include <QList> #include <QMutableListIterator> { public: ~parentObject(){} protected: void deleteSelected(); }; class child1 : public parentObject { public: ~child1(){} void deleteSelect() { delete this; } }; class child2 : public parentObject { public: {} ~child2(){ } void deleteSelect() { delete this; } }; class child3 : public parentObject { public: ~child3(){} void deleteChild2( child2* c ) { c->deleteSelect(); delete this; //feby } /*void deleteSelect() { delete this; }*/ }; int main(int argc, char *argv[]) { parentObject* obj = new parentObject; child1* c11 = new child1( obj ); c11->setObjectName ( "child1" ); child1* c12 = new child1(obj); c12->setObjectName ( "child1" ); child1* c13 = new child1(obj); c13->setObjectName ( "child1" ); child2* c21 = new child2(obj); c21->setObjectName ( "child2" ); child2* c22 = new child2(obj); c22->setObjectName ( "child22" ); child2* c23 = new child2(obj); c23->setObjectName ( "child2" ); child3* c31 = new child3(obj); c31->setObjectName ( "child3" ); QMutableListIterator<QObject*> it(list); while( it.hasNext() ) { qDebug() << tmpObj->objectName(); { c31->deleteChild2( c22 ); it.remove(); list = obj->children(); // reinitialising the "list" it = list; // reinitialising the "Iterator" it.toFront(); // move the iterator the "Front" , before first item. } } return 0; }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:
QMutableListIterator<QObject*> it(list); while( it.hasNext() ) { qDebug() << tmpObj->objectName(); { c31->deleteChild2( c22 ); it.remove(); list = obj->children(); // reinitialising the "list" it = list; // reinitialising the "Iterator" it.toFront(); // move the iterator the "Front" , before first item. } }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
Why not put it into the class destructor? That's what it is for, isn't it?
So why not keep a pointer directly to this object instead of searching for it in the list of all children?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.
Do a recursion over the tree instead of using a flat list.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.
This is not an option.here after deleteChild2(), i am reinitialising the list, iterator.
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.
Yes I do exactly that. Something like thisWhy not put it into the class destructor? That's what it is for, isn't it?
Qt Code:
void class: deleteSelected() { if( isSelected ) delete this; // calls the destructor } class::~class() { //do other stuffs like unselecting and then setting some properties }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.Qt Code:
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
Can you tell me how...Do a recursion over the tree instead of using a flat list.
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
What's the point of checking it for selected if you don't know if it is selected (as you mention below)?
So keep a list.Because there can be any number of objects
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.and I dont know in advance which object the user has selected at run time,
I suggest you do it. You'll solve many issues this way.There can be any number selected 1, 2, 3 etc objects. So I dont I can keep a pointer directly to this object.
More or less like this:Can you tell me how...
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.Qt Code:
if(type = o->metaObject()->className()) delete o; else deleteChild(child, type); } }To copy to clipboard, switch view to plain text mode
veda (22nd May 2007)
Why not so? You go backward ...and you can kill the object anytime.
Qt Code:
QMutableListIterator<QObject*> it(list); it.toBack(); while( it.hasPrevious() ) { qDebug() << tmpObj->objectName(); { c31->deleteChild2( c22 ); it.remove(); } }To copy to clipboard, switch view to plain text mode
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:
QObjectList *list; QListIterator<QObject*> *it; QObject *obj; list = new QObjectList( children() ); if( list->count() != 0 ) { it = new QListIterator<QObject*>( *list ); while ( it->hasNext() ) { obj = it->next(); if( obj->isA( "myObject" ) ) ((myObject *)obj)->deleteSelected(); } delete it; } delete list;To copy to clipboard, switch view to plain text mode
New code
Qt Code:
for(; it!=list.end(); ++it) { if( ((myobject *)(*it))->isSelected() ) selectedList.append( *it ); } { ((myobject*)obj)->deleteSelected(); }To copy to clipboard, switch view to plain text mode
Veda
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?So as you see the order is in general undefined. At least I wouldn't count on it being definedOriginally Posted by QObject docs:
![]()
Bookmarks