Results 1 to 13 of 13

Thread: Probelm after porting from Qt 3.3.4 to Qt 4.2.2

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

    Default Probelm after porting from Qt 3.3.4 to Qt 4.2.2

    Hai

    In our application we have developed a "Chemisty Molecule Drawing Chanvas" ,with some other features.
    We are now porting the application from Qt3.3.4 to Qt4.2.2.

    Here am attaching my code snippet which explains our framework ( precised ). main.cpp will explain the whole thing what we are trying to achive
    This is working in Qt3 , but in Qt4 it gives run time exceptions.


    Could you please help me out to port the same senario in Qt4.
    thanks in advance.

    N:B . This code snippet will work only in Qt3.3.4 .
    Attached Files Attached Files
    Last edited by joseph; 30th May 2007 at 08:16.

  2. #2
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Probelm after porting from Qt 3.3.4 to Qt 4.2.2

    Ok, no time to attach:
    childobject.cpp
    Qt Code:
    1. #include "childObject.h"
    2.  
    3. Atom::Atom(QObject *parent)
    4. :QObject(parent)
    5. {
    6. setObjectName( "Atom" );
    7. isSelected = false;
    8. }
    9.  
    10. Atom::~Atom()
    11. {}
    12.  
    13. void Atom::deleteSelected()
    14. {
    15. if( isSelected )
    16. delete this;
    17. }
    18. void Atom::setSelected( bool flag )
    19. {
    20. isSelected = flag;
    21. }
    22.  
    23. Bond::Bond(QObject *parent)
    24. :QObject(parent)
    25. {
    26. setObjectName( "Bond" );
    27. isSelected = false;
    28. }
    29.  
    30. Bond::~Bond()
    31. {
    32. emit beingDeleted(this);
    33. }
    34.  
    35. void Bond::setSelected( bool flag )
    36. {
    37. isSelected = flag;
    38. }
    39.  
    40. bool Bond::selected()
    41. {
    42. return isSelected;
    43. }
    44.  
    45. void Bond::deleteSelected()
    46. {
    47. if( isSelected )
    48. {
    49. delete this;
    50. }
    51. }
    52. Ring::Ring(QObject *parent)
    53. :QObject(parent)
    54. {
    55. setObjectName( "Ring" );
    56. isSelected = false;
    57. }
    58.  
    59. Ring::~Ring()
    60. {}
    61.  
    62. void Ring::setSelected( bool flag )
    63. {
    64. isSelected = flag;
    65. }
    66.  
    67. bool Ring::selected()
    68. {
    69. return isSelected;
    70. }
    71.  
    72. void Ring::deleteSelected()
    73. {
    74. if( isSelected )
    75. {
    76. delete this;
    77. }
    78. }
    79.  
    80. void Ring::addBond(Bond * b)
    81. {
    82. connect( b, SIGNAL(beingDeleted(QObject *)),
    83. this, SLOT(childBeingDeleted(QObject *)) );
    84. }
    85.  
    86. void Ring::childBeingDeleted(QObject *)
    87. {
    88. /*delete this;*/
    89. }
    To copy to clipboard, switch view to plain text mode 
    parentobject.cpp
    Qt Code:
    1. #include "parentobject.h"
    2. #include "childObject.h"
    3. #include <qobject>
    4.  
    5. Molecule::Molecule(QObject *parent)
    6. : QObject(parent)
    7. {
    8. isSelected = false;
    9. _ring = 0;
    10. }
    11.  
    12. Molecule::~Molecule()
    13. {
    14. if( isSelected ){
    15. isSelected = false;
    16. }
    17. }
    18.  
    19. void Molecule::createRing( Bond* b)
    20. {
    21. if( !_ring )
    22. {
    23. _ring = new Ring( this );
    24. }
    25. _ring->addBond(b);
    26. }
    27.  
    28. void Molecule::deleteSelected()
    29. {
    30. if( isSelected ){
    31. delete this;
    32. return;
    33. }
    34. QList<QObject*> list;
    35. QObject *obj;
    36. list = children();
    37.  
    38. foreach( obj, children() )
    39. {
    40. if( obj )
    41. {
    42. qDebug( obj->objectName().toAscii().constData() );
    43. if( obj->objectName() == QString("Bond") )
    44. {
    45. bool sel = ((Bond*)obj)->selected();
    46. if( sel )
    47. {
    48. list.removeAll( obj );
    49. ((Bond*)obj)->deleteSelected();
    50. obj = NULL;
    51. }
    52. }
    53. }
    54. }
    55. }
    To copy to clipboard, switch view to plain text mode 
    You had several problem there, so I corrected them:
    - a QObject automatically deletes its children, so no need to connect and delete the Ring
    - QObjectList and QObjectListIt were replaced ( by me ).
    - I added a selected() function. It just returns is selected.

    Note: I'm surprised this worked in Qt3

    EDIT: some of the code I posted might be redundant. So feel free to remove those parts.

    Regards
    Last edited by marcel; 30th May 2007 at 08:56.

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

    Default Re: Probelm after porting from Qt 3.3.4 to Qt 4.2.2

    I have tried Your code( Qt4 ) .
    But this is not what i want. You have given a solution which does not serve my purpose.

    My purpose :-
    When i delete a "Bond_object" ( is selected ), the "Ring_object" too has to be deleted ( that's why i used
    Qt Code:
    1. delete this ; emit childBeeingDeleted();
    To copy to clipboard, switch view to plain text mode 
    ).

    In main.cpp the explanation what i have given is,if a "Bond "( selected ) is deleted ,the "Ring" ( A closed polygon ) also should be deleted.
    In the "Molecule_diagram" you cann't see the "Ring_object" ,but logically we are creating it ( Ring Molecule::_ring ).


    What you did:-
    You are deleting a "bond_object" ( selected ). but the "Ring_object" still exists in MOLECULE object.


    Note: I'm surprised this worked in Qt3
    Why...???. Please try it in Qt3 and see the output first.

  4. #4
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Probelm after porting from Qt 3.3.4 to Qt 4.2.2

    But both Bond and Ring are QObjects.
    Ring is a child of Bond.
    When you delete Bond, it automatically deletes all its children, meaning Ring( you can test this by putting a breakpoint in the destructor of Ring, or use qDebug, whatever ).

    Ring will not remain in Molecule's hierarchy because Bond was removed, along with it's children.

    Using QObject has some other implications than the obvious ones.

    Regards

  5. #5
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Probelm after porting from Qt 3.3.4 to Qt 4.2.2

    Anyway, that was the reason your app crashed.
    When you iterated through the child list, you encountered child object( Rings ), that were deleted by Bond objects.

    Regards

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

    Default Re: Probelm after porting from Qt 3.3.4 to Qt 4.2.2

    Sorry marcel. You are little confused , let me explain the class hierarchy first.

    Qt Code:
    1. ---------------------------------------
    2. | QObject |
    3. ---------------------------------------
    4. ^ ^ ^ ^
    5. | | | |
    6. | | | |
    7. Molecule | | |
    8. | | |
    9. Atom | |
    10. | |
    11. Bond |
    12. Ring
    To copy to clipboard, switch view to plain text mode 






    In my senario "Molecule_object" is the parent of "Atom /Bond " objects.
    see main.cpp ...
    Qt Code:
    1. //children of molecule, 3 atoms, 3 bonds
    2. //Atoms
    3. Atom* atom1 = new Atom( molecule );
    4. Atom* atom2 = new Atom( molecule );
    5. Atom* atom3 = new Atom( molecule );
    6.  
    7. //bonds
    8. Bond* bond1 = new Bond( molecule );
    9. Bond* bond2 = new Bond( molecule );
    10. Bond* bond3 = new Bond( molecule );
    To copy to clipboard, switch view to plain text mode 

    And " Molecule_object " has a "Ring" , see the code ..

    Qt Code:
    1. class Molecule : public QObject
    2. {
    3.  
    4. ---
    5. ---
    6.  
    7. private :
    8. Ring _ring* ;
    9.  
    10. }
    To copy to clipboard, switch view to plain text mode 


    In main.cpp..

    Qt Code:
    1. //In Molecule , create a RING [ using function Molecule::createRing( Bond * ) ]
    2. //A ring is a closed polygon [ chemistry term ].
    3. molecule->createRing( bond1 );
    4. molecule->createRing( bond2 );
    5. molecule->createRing( bond3 );
    To copy to clipboard, switch view to plain text mode 



    So "Ring_object " is NOT A CHILD of "Bond_object".
    Instead "Ring_Object" is getting created in a "Molecule_object" [ using function Molecule::createRing( Bond * ) ]
    see the code..
    Qt Code:
    1. void Molecule::createRing( Bond* b)
    2. {
    3. if( !_ring )
    4. {
    5. _ring = new Ring( this );
    6. }
    7. _ring->addBond(b);
    8. }
    To copy to clipboard, switch view to plain text mode 


    thanks
    Last edited by joseph; 30th May 2007 at 10:58.

  7. #7
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Probelm after porting from Qt 3.3.4 to Qt 4.2.2

    Yes, of course you are right. Sorry.
    I looked again at that diagram now and I get it.
    Here's the solution too:
    Qt Code:
    1. void Molecule::deleteSelected()
    2. {
    3. if( isSelected ){
    4. delete this;
    5. return;
    6. }
    7. QList<QObject*> list;
    8. QObject *obj;
    9.  
    10. foreach( obj, children() )
    11. {
    12. if( obj )
    13. {
    14. qDebug( obj->objectName().toAscii().constData() );
    15. if( obj->objectName() == QString("Bond") )
    16. {
    17. bool sel = ((Bond*)obj)->selected();
    18. if( sel )
    19. list.append( obj );
    20. }
    21. }
    22. }
    23.  
    24. while( list.count() )
    25. {
    26. Bond* b= (Bond*)list.takeAt( 0 );
    27. b->deleteSelected();
    28. }
    29. }
    To copy to clipboard, switch view to plain text mode 

    As for the rest of the code, you should keep it as you already had it, meaning you must still connect the ring to bond deletion.

    And this works, just tested it.

    Regards.

  8. #8
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Probelm after porting from Qt 3.3.4 to Qt 4.2.2

    The idea is not to act in any way on the children list of a QObject while deleting items from it.

    I thought to delay the deletion, and split the process in two steps, as you can see in my previous post.

    Regards

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

    Default Re: Probelm after porting from Qt 3.3.4 to Qt 4.2.2

    Quote Originally Posted by marcel View Post
    The idea is not to act in any way on the children list of a QObject while deleting items from it.

    I thought to delay the deletion, and split the process in two steps, as you can see in my previous post.

    Regards
    Qt Code:
    1. Consider this scenario...
    2.  
    3. -----
    4. / \__> atom1
    5. | |
    6. | |--> bond1
    7. | |__> atom2
    8. \ /
    9. -----
    To copy to clipboard, switch view to plain text mode 
    Now there are 8 atoms, 8 bonds and a ring. I select atom1,
    bond1, and atom2. So the "list" contains 3 items ( atom1, bond1, atom2).

    Now I iterate over the list.
    atom1 deletes all its neighbours including bond1( which
    is a neighbour of atom1 ) and the ring.

    Then we go to next iteration, the application crashes as the next item
    in the list is "bond1" which is already deleted.

    Fails....

  10. #10
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Probelm after porting from Qt 3.3.4 to Qt 4.2.2

    Yes, my solution is somewhat particular.
    This does not mean that there isn't a general one.
    Unfortunately I am at work now, but I'll be happy to help once I'm done here.

    Regards

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

    Default Re: Probelm after porting from Qt 3.3.4 to Qt 4.2.2

    Quote Originally Posted by marcel View Post
    Yes, my solution is somewhat particular.
    This does not mean that there isn't a general one.
    Unfortunately I am at work now, but I'll be happy to help once I'm done here.

    Regards
    Waiting eagerly....
    Thanks..

  12. #12
    Join Date
    Oct 2006
    Posts
    279
    Thanks
    6
    Thanked 40 Times in 39 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Probelm after porting from Qt 3.3.4 to Qt 4.2.2

    Hi,
    here's a suggestion:
    Qt Code:
    1. void Molecule::deleteSelected()
    2. {
    3. if( isSelected ){
    4. deleteLater();
    5. return;
    6. }
    7.  
    8. foreach( Bond *bond, findChildren<Bond*>() )
    9. bond->deleteSelected();
    10. }
    To copy to clipboard, switch view to plain text mode 
    In this case you are not iterating and deleting the children list(dangerous!), but you are implicitely working on a copy.
    Also you can remove the setName() calls, since you are only using the class names. You can get to them by calling QMetaObject::className()

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

    Default Re: Probelm after porting from Qt 3.3.4 to Qt 4.2.2

    Consider this scenario...

    Suppose there are 5 bonds( bond1, .... bond5), from the foreach statement,
    Now
    1) First Iteration leads to deletion of bond1 and bond3;
    2) Second iteration works fine.
    3) Third iteration, OH!!! Crashes, the bond is already deleted in
    iteration1.

    Fails...
    Please provide some solution where the list gets updated
    automatically like how it worked in Qt3.

    Please run the same code without any changes in Qt3 (provided in first post) and then
    run again the same code after porting to Qt4, you
    can find the differences..

    Please help

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.