Results 1 to 13 of 13

Thread: Deleting a child widget

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Dec 2008
    Location
    Istanbul, TURKEY
    Posts
    537
    Thanks
    14
    Thanked 13 Times in 13 Posts
    Qt products
    Qt4
    Platforms
    Windows Android

    Default Deleting a child widget

    Hi,

    I have widget;

    Qt Code:
    1. ...
    2.  
    3. MyWidget my_widget = new MyWidget(parentWidget/*this*/);
    4.  
    5. ...
    To copy to clipboard, switch view to plain text mode 

    when I delete the parent like;

    Qt Code:
    1. delete parentWidget;
    To copy to clipboard, switch view to plain text mode 

    it deletes the child but it doesn't call the MyWidget's destructor right? If we want to call MyWidget's destructor, we need delete the child MyWidget explicitly like?


    Qt Code:
    1. delete myWidget;
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    May 2012
    Posts
    37
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Deleting a child widget

    Your destructor will be called when the parent of the widget is deleted. You probably have a derived class and no virtual destructor?

  3. #3
    Join Date
    Dec 2008
    Location
    Istanbul, TURKEY
    Posts
    537
    Thanks
    14
    Thanked 13 Times in 13 Posts
    Qt products
    Qt4
    Platforms
    Windows Android

    Default Re: Deleting a child widget

    Hi,

    It's virtual but somehow deletion performed implicitly.

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Deleting a child widget

    Quote Originally Posted by Kwakkie View Post
    You probably have a derived class and no virtual destructor?
    In a QWidget subclass you always have a virtual destructor because it inherits its virtualness from the destructor of the root base class, which is QObject and this one has a virtual destructor.

    So in a situation like this
    Qt Code:
    1. class MyWidget : public QWIdget
    2. {
    3. //....
    4. };
    5.  
    6. MyWidget *myWidget = new MyWidget;
    7. QWidget *widget = myWidget;
    8. QObject *object = myWidget;
    To copy to clipboard, switch view to plain text mode 

    A delete call on any of those variables will result in calls to ~MyWidget then ~QWidget then ~QObject

    Cheers,
    _

  5. #5
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,324
    Thanks
    316
    Thanked 871 Times in 858 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Deleting a child widget

    Qt Code:
    1. MyWidget my_widget = new MyWidget(parentWidget/*this*/);
    To copy to clipboard, switch view to plain text mode 

    This code won't even compile, so it obviously isn't what you are actually doing in your own code. If you meant to say (and are doing something like this in your own code):

    Qt Code:
    1. MyWidget * my_widget = new MyWidget(parentWidget/*this*/);
    To copy to clipboard, switch view to plain text mode 

    then calling "delete parentWidget" will do exactly what anda_skoa said will happen.

    But I can't think of any case in Qt where you would want to call delete on a widget instance; deletion is handled automatically by the Qt parent-child ownership framework. Typically the top-most widget in an application's GUI hierarchy (as well as modal dialogs and the like) are created on the stack, not by "new", and delete themselves when they leave scope. All other widgets are created with "new" and are assigned a parent, and that parent is then in charge of their lifetimes.

  6. #6
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Deleting a child widget

    Just to give you an example of needing to call delete on a Qt class instance - if you remove an item from a QGraphicsScene then you have ownership and will need to delete it manually.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  7. #7
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,324
    Thanks
    316
    Thanked 871 Times in 858 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Deleting a child widget

    Just to give you an example of needing to call delete on a Qt class instance - if you remove an item from a QGraphicsScene then you have ownership and will need to delete it manually.
    Yes, agreed. I think of this as a special case, though. Since QGraphicsScene contents are often dynamic, there needs to be special handling of item addition and removal. QWidget hierarchies are usually more static. But if you remove an item from a scene and that item itself has child items, when you delete the item, its children will automatically be deleted by the parent-child ownership protocol.

    Constructed "top"
    Constructed "a"
    Constructed "b"
    Constructed "c child of a"
    Destroyed "top"
    Destroyed "a"
    Destroyed "c child of a"
    Destroyed "b"
    This is interesting - I thought "top" would have been shown as being destroyed last. My understanding of C++ construction was that construction proceeded from most-derived up to base class, and destruction proceeded from base class downward to most-derived, so the body of the destructor for the most-derived class would be executed last. Thus I would have expected that the messages for destruction would show "c", then "a", "b", and finally "top".

    Obviously my understanding must be faulty, or is this behaviour an artifact of qDebug()?

    Edit ---

    My understanding of C++ construction was that construction proceeded from most-derived up to base class, and destruction proceeded from base class downward to most-derived,
    Duh (after performing a head-whack) - no this is completely backward; construction goes up the hierarchy, with the body of the base class executed first, followed by each derived class, until finally the most-derived class's constructor gets executed. Destruction goes the other way. So the qDebug() statements as originally given do show things happening in the order they actually occur. My apologies for not having had enough coffee before starting to type.
    Last edited by d_stranz; 14th December 2012 at 18:50.

  8. #8
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Deleting a child widget

    Quote Originally Posted by d_stranz View Post
    This is interesting - I thought "top" would have been shown as being destroyed last. My understanding of C++ construction was that construction proceeded from most-derived up to base class, and destruction proceeded from base class downward to most-derived, so the body of the destructor for the most-derived class would be executed last. Thus I would have expected that the messages for destruction would show "c", then "a", "b", and finally "top".

    Obviously my understanding must be faulty, or is this behaviour an artifact of qDebug()?
    This isn't a demo of c++ inheritance hierarchy, it is Qt parent-child hierarchy example.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  9. #9
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,324
    Thanks
    316
    Thanked 871 Times in 858 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Deleting a child widget

    This isn't a demo of c++ inheritance hierarchy, it is Qt parent-child hierarchy example.
    Well, yes it is, in a way. MyWidget is derived from QWidget and then from QObject, so I would expect that the body of ~QObject would be executed before the bodies of ~QWidget and ~MyWidget. This would imply that the children of the "top" widget (and the "a" widget) would be destructed by ~QObject (and thus their MyWidget destructors would execute) prior to the body of the MyWidget destructor for "top" getting executed. Thus the qDebug() statements should be issued in the order I stated.

    I guess I'll just have to build this example and step through it in the debugger.

    Edit -- never mind - see my edit a few posts above. I'll just slink away with my tail between my legs and work on why I can't get OpenGL textures to display in a QGLWidget.
    Last edited by d_stranz; 14th December 2012 at 18:52.

  10. #10
    Join Date
    May 2012
    Posts
    37
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Deleting a child widget

    Quote Originally Posted by anda_skoa View Post
    In a QWidget subclass you always have a virtual destructor because it inherits its virtualness from the destructor of the root base class, which is QObject and this one has a virtual destructor.

    So in a situation like this
    Qt Code:
    1. class MyWidget : public QWIdget
    2. {
    3. //....
    4. };
    5.  
    6. MyWidget *myWidget = new MyWidget;
    7. QWidget *widget = myWidget;
    8. QObject *object = myWidget;
    To copy to clipboard, switch view to plain text mode 

    A delete call on any of those variables will result in calls to ~MyWidget then ~QWidget then ~QObject

    Cheers,
    _
    I know that, But what if he has class A that is derived from class B, and B is derived from QWidget. If B has no virtual destructor...

  11. #11
    Join Date
    Dec 2008
    Location
    Istanbul, TURKEY
    Posts
    537
    Thanks
    14
    Thanked 13 Times in 13 Posts
    Qt products
    Qt4
    Platforms
    Windows Android

    Default Re: Deleting a child widget

    Hi,

    This code won't even compile, so it obviously isn't what you are actually doing in your own code. If you meant to say (and are doing something like this in your own code):
    Sure. But it seems a bit pointless highlighting to me.

    But I can't think of any case in Qt where you would want to call delete on a widget instance
    mentioned "how can we" quite well above.

    A delete call on any of those variables will result in calls to ~MyWidget then ~QWidget then ~QObject
    I certainly agree and this is how I expected. But no destructor of MyWidget being called unless I delete it explicitly.

  12. #12
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Deleting a child widget

    Quote Originally Posted by Kwakkie View Post
    I know that, But what if he has class A that is derived from class B, and B is derived from QWidget. If B has no virtual destructor...
    B MUST have virtual dtor since QObject has virtual dtor.

    Quote Originally Posted by zgulser View Post
    Hi,
    I certainly agree and this is how I expected. But no destructor of MyWidget being called unless I delete it explicitly.
    Show your example code. If MyWidget instance has a parent then the dtor will be called when the parent dies.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  13. #13
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Deleting a child widget

    But no destructor of MyWidget being called unless I delete it explicitly.
    Sure they are. For a demo:
    Qt Code:
    1. #include <QtGui>
    2. #include <QDebug>
    3. class MyWidget: public QWidget
    4. {
    5. Q_OBJECT
    6. public:
    7. MyWidget(const QString &name, QWidget *p = 0): QWidget(p) {
    8. setObjectName(name);
    9. qDebug() << "Constructed" << objectName();
    10. }
    11. ~MyWidget() {
    12. qDebug() << "Destroyed" << objectName();
    13. }
    14. };
    15.  
    16.  
    17. int main(int argc, char **argv) {
    18. QApplication app(argc, argv);
    19.  
    20. MyWidget *top = new MyWidget("top");
    21. MyWidget *a = new MyWidget("a", top);
    22. MyWidget *b = new MyWidget("b", top);
    23. MyWidget *c = new MyWidget("c child of a", a);
    24.  
    25. delete top;
    26.  
    27. return 0;
    28. }
    29. #include "main.moc"
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. Constructed "top"
    2. Constructed "a"
    3. Constructed "b"
    4. Constructed "c child of a"
    5. Destroyed "top"
    6. Destroyed "a"
    7. Destroyed "c child of a"
    8. Destroyed "b"
    To copy to clipboard, switch view to plain text mode 

    Perhaps in your real program you are not looking at or deleting the instances you think you are.

Similar Threads

  1. Deleting characters in QLineEdit widget
    By Santiago in forum Newbie
    Replies: 2
    Last Post: 11th November 2011, 14:18
  2. Deleting children of a widget
    By ComServant in forum Newbie
    Replies: 5
    Last Post: 7th October 2011, 00:09
  3. deleting a widget
    By john_god in forum General Programming
    Replies: 1
    Last Post: 30th December 2010, 09:36
  4. Replies: 7
    Last Post: 19th May 2010, 13:24
  5. Replies: 1
    Last Post: 28th July 2006, 14:10

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.