Results 1 to 10 of 10

Thread: Qt widget setParent

  1. #1
    Join Date
    Jan 2007
    Location
    Paris
    Posts
    459
    Thanks
    98
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt5

    Default Qt widget setParent

    Hey there,

    My app is heavily based on widget.
    For some reason they don't seem to be deleted.
    I've come up with the following settable widget code :

    Qt Code:
    1. #include "ZeSettableLayout.h"
    2.  
    3. #include "ZeLog.h"
    4.  
    5. //=============================================================================
    6. //=============================================================================
    7.  
    8. ZeSettableLayout::ZeSettableLayout(QWidget * parent) :
    9. QWidget(parent),
    10. mLayout(this)
    11. {
    12. mSettableLayout = 0;
    13. mWidget = 0;
    14.  
    15. getLayout().setMargin(0);
    16. getLayout().setSpacing(0);
    17.  
    18. mOldParent = NULL;
    19. }
    20.  
    21. //=============================================================================
    22. //=============================================================================
    23.  
    24. ZeSettableLayout::~ZeSettableLayout()
    25. {
    26. Clear();
    27. }
    28.  
    29. //=============================================================================
    30. //=============================================================================
    31.  
    32. void ZeSettableLayout::setLayout(QLayout & settableLayout,
    33. int stretch)
    34. {
    35. Clear();
    36.  
    37. mSettableLayout = &settableLayout;
    38.  
    39. getLayout().addLayout(mSettableLayout, stretch);
    40. }
    41.  
    42. //=============================================================================
    43. //=============================================================================
    44.  
    45. void ZeSettableLayout::setWidget(QWidget & widget,
    46. int stretch,
    47. Qt::Alignment alignment)
    48. {
    49. Clear();
    50.  
    51. mWidget = &widget;
    52.  
    53. // Saving old parent to restore it at deletion
    54. mOldParent = getWidget().parentWidget();
    55.  
    56. getLayout().addWidget(mWidget, stretch, alignment);
    57. getWidget().show();
    58. }
    59.  
    60. //=============================================================================
    61. //=============================================================================
    62.  
    63. void ZeSettableLayout::Clear()
    64. {
    65. if (mSettableLayout)
    66. {
    67. getLayout().removeItem(mSettableLayout);
    68.  
    69. mSettableLayout = NULL;
    70. }
    71.  
    72. if (mWidget)
    73. {
    74. getLayout().removeWidget(mWidget);
    75.  
    76. // Retoring old parent for deletion
    77. getWidget().setParent(mOldParent);
    78. mOldParent = NULL;
    79.  
    80. //getWidget().hide();
    81. mWidget = NULL;
    82. }
    83. }
    To copy to clipboard, switch view to plain text mode 

    At some point I'm backuping the old widget's parent, to set it back when my settable widget is deleted :
    line 77 getWidget().setParent(mOldParent);

    It seems to prevent the widget from deletion, even when I'm calling delete widget, I'm not sure why.

  2. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Qt widget setParent

    You're asking for troubles by allocating widgets and layouts on the stack... It's not really safe, once a parent deletes a child allocated on the stack you'll get a crash.
    J-P Nurmi

  3. #3
    Join Date
    Jan 2007
    Location
    Paris
    Posts
    459
    Thanks
    98
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt5

    Default Re: Qt widget setParent

    You're not the first to tell me so.

    Actually,
    I'm not sure what is wrong with allocating a Widget / Layout on the stack.

    Of course if you use them badly it will most likely crash,
    but,
    why declaring a layout on an instance's stack would crash anything ?

    You're telling me that a widget on the stack won't be properly deleted in the dtor of my classe instances ?

    Because for me in C++ and it's common knowledge declaring something on the stack has never crashed anything.

  4. #4
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Qt widget setParent

    Quote Originally Posted by bunjee View Post
    You're not the first to tell me so.
    Doesn't that ring any bells?
    Actually,
    I'm not sure what is wrong with allocating a Widget / Layout on the stack. Of course if you use them badly it will most likely crash,
    but,
    why declaring a layout on an instance's stack would crash anything ?
    It's not about using objects allocated on the stack "badly" or "properly". It's because parents take ownership of their children. A parent deletes all of its children. A parent widget deletes its layout. A parent widget deletes its child widgets. When a parent deletes something that was allocated on stack, you'll get a crash.
    You're telling me that a widget on the stack won't be properly deleted in the dtor of my classe instances ?
    A constructor gets called whenever an object gets destructed. For stack objects this happens when they go out of scope.
    J-P Nurmi

  5. #5
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Qt widget setParent

    QObjects store children as a list containing QObject pointers. When you delete the object or QObject destructor is called, it calls delete on all its children.

    Now you can see the scenario in your case where you allocate QObjects on a stack and it does have parent. When parent is destructed , delete is called on object on stack which crashes your program.

    edit: I was bit late(jpn answered first) but atleast better late than never
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  6. #6
    Join Date
    Jan 2007
    Location
    Paris
    Posts
    459
    Thanks
    98
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt5

    Default Re: Qt widget setParent

    I don't have any crash with my application .

    My problem is memory.

    According to Qt Doc :
    Warning: It is very unlikely that you will ever need this function. If you have a widget that changes its content dynamically, it is far easier to use QStackedWidget.
    Does setting parent to compromise anything for deletion I'm not aware off ?

  7. #7
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Qt widget setParent

    Quote Originally Posted by bunjee View Post
    It seems to prevent the widget from deletion, even when I'm calling delete widget, I'm not sure why.
    What does this mean, actually? What do you mean with "prevent something from deletion"?

    Quote Originally Posted by bunjee View Post
    You're not the first to tell me so.
    Indeed, seems you've been warned before in this thread by a bunch of people. Why do you insist doing it wrong? Have you seen any Qt examples allocating widgets or layouts on the stack (excluding main() and modal dialogs)? Or did you ever actually read any of them? Sorry for the tone, but I just don't understand people who regardless of continuous warnings insist of doing things their own (wrong) way.

    Quote Originally Posted by bunjee View Post
    My problem is memory.
    What exact steps did you take to verify this?
    J-P Nurmi

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

    bunjee (30th November 2007)

  9. #8
    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: Qt widget setParent

    Quote Originally Posted by bunjee View Post
    You're not the first to tell me so.

    Actually,
    I'm not sure what is wrong with allocating a Widget / Layout on the stack.

    Of course if you use them badly it will most likely crash,
    but,
    why declaring a layout on an instance's stack would crash anything ?

    You're telling me that a widget on the stack won't be properly deleted in the dtor of my classe instances ?
    You are considering yourself an expert, so I'll give you an "expert" reply - allocating layouts and child widgets on the stack causes crashes, because of trying to deallocate the same area of memory twice. As you are an expert, you'll surely know what I'm talking about.


    Because for me in C++ and it's common knowledge declaring something on the stack has never crashed anything.
    Oh really? Consider this:

    Qt Code:
    1. int main(){
    2. int x;
    3. delete &x;
    4. return 0;
    5. }
    To copy to clipboard, switch view to plain text mode 
    Is this going to crash the application or not?

  10. #9
    Join Date
    Jan 2007
    Location
    Paris
    Posts
    459
    Thanks
    98
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt5

    Default Re: Qt widget setParent

    So you mean there is a "delete" layout and a "delete" widget in the Qt code.

    In that case I don't understand why my program is not crashing.

    I'll go check the sources to see how this works.

  11. #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: Qt widget setParent

    Because you are lucky and the order in which the compiler deletes objects that goes out of scope is exactly the one that is needed to avoid a crash. I don't want to inspect your code right now, so I'll give an easy example:
    Qt Code:
    1. #include <QObject>
    2. int main(int argc, char **argv){
    3. QObject o1;
    4. QObject o2;
    5. o2.setParent(&o1);
    6. return 0;
    7. }
    To copy to clipboard, switch view to plain text mode 

    Run this application and see if it crashes. Then switch lines 3. and 4. and run it again and again see if it crashes.

  12. The following 2 users say thank you to wysota for this useful post:

    bunjee (30th November 2007), dsab123 (6th July 2012)

Similar Threads

  1. Drawing a widget in QItemDelegate's paint method
    By darkadept in forum Qt Programming
    Replies: 17
    Last Post: 11th August 2009, 06:15
  2. Replies: 3
    Last Post: 17th October 2007, 13:52
  3. transparent background of the main widget
    By nagpalma in forum Qt Programming
    Replies: 2
    Last Post: 4th May 2007, 18:52
  4. Controlling which widget on top layer?
    By JonathanForQT4 in forum Qt Programming
    Replies: 6
    Last Post: 22nd March 2007, 15:27
  5. [Qt 4.1.0] Split a widget on demand
    By Townk in forum Qt Programming
    Replies: 3
    Last Post: 17th February 2006, 15:16

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.