Results 1 to 14 of 14

Thread: Removing widget from layout

  1. #1
    Join Date
    Sep 2010
    Posts
    62
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Removing widget from layout

    Hello,

    I'd like to remove a widget from the layout and delete it.

    for this I'd like to use the following source code

    ...
    int cnt;
    QLayoutItem *it;
    MyWidget *w;

    cnt = aVLayout->count();

    for( int i = 0; i < cnt; i++ )
    {
    it = aVLayout->itemAt(0);
    w = ((MyWidget *)(it->widget()));
    aVLayout->removeWidget( w );
    delete w;
    aVLayout->removeItem( it );
    delete it; // SEGMENTATION VIOLATION CRASH!!!
    }

    My questions:
    - Is it necessary to remove and delete the QLayoutItem item?
    - how to do it to avoid the crash?

    In my understanding, the QLayoutItem has been created and added, when the addWidget() method has been called, so when I am removing a widget from the layout and deleting it, also the QLayoutItem shall be removed and deleted. Is it correct?

    I am using Qt 4.6.3

    Thx for your help
    Last edited by lotek; 17th July 2011 at 13:18.

  2. #2
    Join Date
    Apr 2011
    Posts
    124
    Thanks
    1
    Thanked 10 Times in 10 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Windows Symbian S60

    Default Re: Removing widget from layout

    I suspect you should remove the item first, then delete it. Since it owns the widget, there would be no need to separately delete the widget. In your code you've deleted the widget while the item still "owns" it, so the item destructor attempts to delete the widget again.

  3. #3
    Join Date
    Apr 2010
    Posts
    769
    Thanks
    1
    Thanked 94 Times in 86 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Removing widget from layout

    This approach can never work; you're guaranteed to walk off the end of the layout vector once you remove something from it, because you keep looping over the entire initial count before removal.

  4. #4
    Join Date
    May 2010
    Location
    Romania
    Posts
    1,021
    Thanks
    62
    Thanked 260 Times in 246 Posts
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Removing widget from layout

    A simple approach for this kind of "dynamic" layout is to keep a QList (or other container) of pointers to Widgets and use those pointers to add/remove from the layout.

    //you can code add and remove helper functions that add or remove widget pointer both to layout and to QList.
    LE:
    the remove function also delete the widget pointer.

  5. #5
    Join Date
    Sep 2010
    Posts
    62
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Removing widget from layout

    ???
    I am always removing the first item cnt times. What's wrong about it?

    I've corrected the attached source code, there was the copy & paste bug, the name of the layout was the real one instead of the "aVLayout" used for this example.


    Added after 4 minutes:


    Hello Zlatomir,

    This is the possible workaround. But why my code does not work?
    And what about empty (without QWidget) QLayout items? Shall they stay ?
    Is it a bug or feature?
    Last edited by lotek; 17th July 2011 at 13:38.

  6. #6
    Join Date
    May 2010
    Location
    Romania
    Posts
    1,021
    Thanks
    62
    Thanked 260 Times in 246 Posts
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: Removing widget from layout

    I don't have time right now to check the QLayoutItem documentation, but you can check it, my guess you shouldn't delete it (or anyway what you want is to delete the contained widget <if any>)

  7. #7
    Join Date
    Sep 2010
    Posts
    62
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Removing widget from layout

    Quote Originally Posted by SixDegrees View Post
    This approach can never work; you're guaranteed to walk off the end of the layout vector once you remove something from it, because you keep looping over the entire initial count before removal.
    ???
    I am always removing the first item cnt times. What's wrong about it?


    Added after 8 minutes:


    Quote Originally Posted by Zlatomir View Post
    I don't have time right now to check the QLayoutItem documentation, but you can check it, my guess you shouldn't delete it (or anyway what you want is to delete the contained widget <if any>)
    Unfortunately, there is no word about it.
    In the void QLayout::removeItem ( QLayoutItem * item )
    it is stated"
    "Removes the layout item item from the layout. It is the caller's responsibility to delete the item."
    ( it is what I attempt do do)

    in the description of void QLayout::removeWidget ( QWidget * widget )
    there is:
    "Removes the widget widget from the layout. After this call, it is the caller's responsibility to give the widget a reasonable geometry or to put the widget back into a layout.
    Note: The ownership of widget remains the same as when it was added."
    Last edited by lotek; 17th July 2011 at 13:49.

  8. #8
    Join Date
    Apr 2011
    Posts
    124
    Thanks
    1
    Thanked 10 Times in 10 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Windows Symbian S60

    Default Re: Removing widget from layout

    Zlatomir, there is no interface (that I can find) to remove a widget from a QLayoutItem -- once it's in the layout item you can only delete the layout item.

    [To the OP:]
    Might we ask why you want to do all this in the first place? Why don't you just delete the entire layout and be done with it?

    At the very least, change your loop to work from the end backwards, or just delete item(0) cnt times.

    And remember, you need to check the item type. An item may be a spacer, or another layout.

    [And thanks to this strange forum software for glomming all my posts together, even though the later ones are directed at the OP.]
    Last edited by DanH; 17th July 2011 at 14:46.

  9. #9
    Join Date
    Sep 2010
    Posts
    62
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Removing widget from layout

    Quote Originally Posted by DanH View Post
    Zlatomir, there is no interface (that I can find) to remove a widget from a QLayoutItem -- once it's in the layout item you can only delete the layout item.

    [To the OP:]
    Might we ask why you want to do all this in the first place? Why don't you just delete the entire layout and be done with it?

    At the very least, change your loop to work from the end backwards,
    or just delete item(0) cnt times.


    And remember, you need to check the item type. An item may be a spacer, or another layout.
    Yes, BUT there IS NO spacers or other layouts, Besides, there is no special treatment for such
    QLayoutItems

    [And thanks to this strange forum software for glomming all my posts together, even though the later ones are directed at the OP.]
    "QLayoutItem -- once it's in the layout item you can only delete the layout item."
    Deleting the QLayoutItem does not delete a widget - checked!
    It is also stated in the description of the layout d-tor - in opposite to QLayoutItems the widgets are not deleted.

    "Might we ask why you want to do all this in the first place? Why don't you just delete the entire layout and be done with it?"
    Well it's a possible workaround. What when I need to exchange only some widgets?

    "At the very least, change your loop to work from the end backwards,"
    It does no matter, I've checked both variants, always the same.
    "or just delete item(0) cnt times."
    ??? that's exactly what I am doing!

    layout and be done with it?

    At the very least, change your loop to work from the end backwards,
    or just delete item(0) cnt times.


    "And remember, you need to check the item type. An item may be a spacer, or another layout."
    Yes, BUT there IS NO spacers or other layouts, Besides, why they should be treated in a special way? They would only return NULL on widget() call.


    Fine, then let's change the Question:
    Is it necessary to remove and delete the QLayoutItem, after removing and deleting of QWidget?

  10. #10
    Join Date
    Apr 2011
    Posts
    124
    Thanks
    1
    Thanked 10 Times in 10 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Windows Symbian S60

    Default Re: Removing widget from layout

    If you delete the widget, you haven't told the layout item it's deleted. The layout item still will attempt to address it. And there's no way to tell the layout item that its widget has been deleted.

  11. #11
    Join Date
    Sep 2010
    Posts
    62
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Removing widget from layout

    Quote Originally Posted by DanH View Post
    If you delete the widget, you haven't told the layout item it's deleted. The layout item still will attempt to address it. And there's no way to tell the layout item that its widget has been deleted.
    Please see the QLayout::removeWidget() method and note that I am using it before deleting the widget

  12. #12
    Join Date
    Apr 2011
    Posts
    124
    Thanks
    1
    Thanked 10 Times in 10 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Windows Symbian S60

    Default Re: Removing widget from layout

    Does removeWidget say you can destroy the widget?

  13. #13
    Join Date
    Sep 2010
    Posts
    62
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Removing widget from layout

    Resolved:
    After looking in the source code:
    removeWidget method also remowes according QLayoutItem.

    It's a pity that it is not well documented.
    Also the API is very misleading - to get a widget at the position one have to get the QLayoutItem first.

  14. #14
    Join Date
    Sep 2008
    Posts
    7
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Removing widget from layout

    Yup it does remove the item and you should destroy both.

    I often use this function when I need to clear a layout:

    Qt Code:
    1. void Class::clearLayout(QLayout *layout) {
    2. if (layout) {
    3. QLayoutItem *item;
    4.  
    5. //the key point here is that the layout items are stored inside the layout in a stack
    6. while((item = layout->takeAt(0)) != 0) {
    7. if (item->widget()) {
    8. layout->removeWidget(item->widget());
    9. delete item->widget();
    10. }
    11.  
    12. delete item;
    13. }
    14. }
    15. }
    To copy to clipboard, switch view to plain text mode 

    The code is easy to read and good looking

Similar Threads

  1. Replies: 8
    Last Post: 5th May 2021, 16:41
  2. mainwindow layout vs widget layout
    By fatecasino in forum Newbie
    Replies: 2
    Last Post: 14th December 2010, 14:45
  3. (Solved) Removing (replacing) central widget
    By frenk_castle in forum Newbie
    Replies: 7
    Last Post: 14th December 2010, 10:02
  4. How to change a widget to other widget in layout?
    By Kevin Hoang in forum Qt Programming
    Replies: 2
    Last Post: 20th March 2010, 10:55
  5. removing child widget
    By db in forum Newbie
    Replies: 1
    Last Post: 16th August 2007, 12:19

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.