Qt - remove all widgets from layout?

前端 未结 12 620
野性不改
野性不改 2020-12-01 01:33

This doesn\'t seem easy. Basically, I add QPushButtons through a function to a layout, and when the function executes, I want to clear the layout first (removi

相关标签:
12条回答
  • 2020-12-01 02:22

    If you don't do anything funny when adding widgets to layouts and layouts to other layouts they should all be reparented upon addition to their parent widget. All QObjects have a deleteLater() slot which will cause the QObject to be deleted as soon as control is returned to the event loop. Widgets deleted in this Manor also delete their children. Therefore you simply need to call deleteLater() on the highest item in the tree.

    in hpp

    QScrollArea * Scroll;
    

    in cpp

    void ClearAndLoad(){
        Scroll->widget()->deleteLater();
        auto newLayout = new QVBoxLayout;
        //add buttons to new layout
        auto widget = new QWidget;
        widget->setLayout(newLayout);
        Scroll->setWidget(widget);
    }
    

    also note that in your example the _layout is a local variable and not the same thing as the _layout in the header file (remove the QVBoxLayout* part). Also note that names beginning with _ are reserved for standard library implementers. I use trailing _ as in var_ to show a local variable, there are many tastes but preceding _ and __ are technically reserved.

    0 讨论(0)
  • 2020-12-01 02:29

    This code deletes all its children. So everything inside the layout 'disappears'.

    qDeleteAll(yourWidget->findChildren<QWidget *>(QString(), Qt::FindDirectChildrenOnly));
    

    This deletes all direct widgets of the widget yourWidget. Using Qt::FindDirectChildrenOnly is essential as it prevents the deletion of widgets that are children of widgets that are also in the list and probably already deleted by the loop inside qDeleteAll.

    Here is the description of qDeleteAll:

    void qDeleteAll(ForwardIterator begin, ForwardIterator end)

    Deletes all the items in the range [begin, end] using the C++ delete > operator. The item type must be a pointer type (for example, QWidget *).

    Note that qDeleteAll needs to be called with a container from that widget (not the layout). And note that qDeleteAll does NOT delete yourWidget - just its children.

    0 讨论(0)
  • 2020-12-01 02:30

    only works for my buttonlist, if the widgets themeselves are deleted, too. otherwise the old buttons are still visible:

    QLayoutItem* child;
    while ((child = pclLayout->takeAt(0)) != 0)
    {
        if (child->widget() != NULL)
        {
            delete (child->widget());
        }
        delete child;
    }
    
    0 讨论(0)
  • 2020-12-01 02:30

    I had a similar case where I have a QVBoxLayout containing dynamically created QHBoxLayout objects containing a number of QWidget instances. For some reason I couldn't get rid of the widgets either by deleting neither the top level QVBoxLayout or the individual QHBoxLayouts. The only solution I got to work was by going through the hierarchy and removing and deleting everything specifically:

    while(!vbox->isEmpty()) {
        QLayout *hb = vbox->takeAt(0)->layout();
        while(!hb->isEmpty()) {
            QWidget *w = hb->takeAt(0)->widget();
            delete w;
        }
        delete hb;
    }
    
    0 讨论(0)
  • 2020-12-01 02:35

    I have a possible solution for this problem (see Qt - Clear all widgets from inside a QWidget's layout). Delete all widgets and layouts in two seperate steps.

    Step 1: Delete all widgets

        QList< QWidget* > children;
        do
        {
           children = MYTOPWIDGET->findChildren< QWidget* >();
           if ( children.count() == 0 )
               break;
           delete children.at( 0 );
        }
        while ( true );
    

    Step 2: Delete all layouts

        if ( MYTOPWIDGET->layout() )
        {
            QLayoutItem* p_item;
            while ( ( p_item = MYTOPWIDGET->layout()->takeAt( 0 ) ) != nullptr )
                delete p_item;
            delete MYTOPWIDGET->layout();
        }
    

    After step 2 your MYTOPWIDGET should be clean.

    0 讨论(0)
  • 2020-12-01 02:36

    You do not write about going the other way, but you could also just use a QStackedWidget and add two views to this, one for each arrangement of buttons that you need. Flipping between the two of them is a non issue then and a lot less risk than juggling various instances of dynamically created buttons

    0 讨论(0)
提交回复
热议问题