从QGridLayout中移除QWidgets

3

我有一个QGridLayout,我在其中添加了自定义的QWidgets

当我尝试删除它们时,它们应该从布局中移除(因为函数layout.count()返回0),但它们仍然显示在界面上,我可以与它们交互。

这是我添加小部件的方法:

void MyClass::addCustomWidget(CustomWidget *_widget, int r, int c)
{
    layout->addWidget(_widget, r, c);
    _widget->show();
}

以下是我删除它们的方法:

void MyClass::clearLayout()
{
    qDebug() << "Layout count before clearing it: " << layout->count();

    int count = layout->count();
    int colums = layout->columnCount();
    int rows = layout->rowCount();

    int i=0;
    for(int j=0; j<rows; j++)
    {
        for(int k=0; k<colums && i<count; k++)
        {
            i++;

            qDebug() << "Removing item at: " << j << "," << k;
            QLayoutItem* item = layout->itemAtPosition(j, k);

            if (!item) continue;

            if (item->widget()) {
                layout->removeWidget(item->widget());
            } else {
                layout->removeItem(item);
            }
            qDebug() << "Removed!";
        }
    }

    qDebug() << "Layout count after clearing it: " << layout->count();
}

有什么方法或提示可以正确地从QGridLayout中删除元素/小部件吗?

附言:我在网上看到很多人在从布局中移除小部件后直接删除小部件(delete _widget)。但是在我的情况下,这是不可能的,因为我需要将这些小部件保存在内存中。


5个回答

4
只是为了明确。您没有“删除”小部件。您只是将它们从布局中移除。从布局中移除只意味着该小部件将不再由此布局管理(调整大小/定位),但这并不意味着该小部件将被“删除”(以C ++方式)。此外,小部件不会神奇地隐藏。从布局中移除后,您的小部件仍然留在其创建/管理的小部件中。因此,此布局的所有者仍将拥有此小部件作为子级(可见子级)。
您必须:
1. 隐藏小部件,或者如果您确定它不再使用,则
2. 使用“delete”关键字删除小部件
另外,您不需要调用removeWidget(item->widget()); removeItem(item)对于所有布局项(即使其中包含小部件)都已足够。

1
我的意图是从布局中移除小部件(并且不再显示它们),但保留在内存中。 我尝试在从布局中移除小部件之前隐藏它们(_widget.hide),这样做起效了,谢谢。 - undefined

4

您还可以使用deleteLater()来避免在迭代过程中维护子项计数的问题:

for (int i = 0; i < gridLayout.count(); i++)
{
   gridLayout.itemAt(i)->widget()->deleteLater();
}

1
感谢您五年后尝试解决这个问题的辛勤努力 ;) - undefined

1

尝试一下

QLayoutItem *child;
while ((child = layout->takeAt(0)) != 0);

它应该是安全的。如果由于任何原因它不能正常工作,您可以使用一组小部件或布局项,每次添加小部件时都会更新。然后要删除,您可以循环遍历集合并从布局中删除每个元素。


0
Header:
class Grid : QGridLayout
{
public:
    Grid(QWidget* parent);
    void addElement(QWidget* element, int x, int y);
    void delElement(int x, int y);
    void resize(int width, int height);
    void clear();
protected:
    QSize size;
};

void Grid::clear(){
    for(int i = 0;i<size.width();i++){
        for(int j = 0;j<size.height();j++){
            QLayoutItem* item = takeAt(i*size.width() + j);
            if(item != NULL) delete item;
        }
    }
}

0

这些答案对我都没有用。在我的情况下,我有几个对象,每个对象都有自己的QChartView。用户选择要查看的对象,然后主窗口中央的公共区域会更新为用户选择的对象的QChartView。这本应该很简单,只需从图表区域移除小部件,添加一个新的。最终对我有效的方法是:

while( QLayoutItem* item = ui->mPlotArea->layout()->takeAt(0) )
{
    item->widget()->setVisible(false);
    ui->mPlotArea->layout()->removeItem(item);
}

ui->mPlotArea->layout()->addWidget( pv );
pv->setVisible(true);

其中mPlotArea是一个QFrame,而pvQChartView的派生类。我无法解释为什么其他答案没有起作用,但我花了几个小时尝试不同的小部件和不同的移除方式,而不是删除、整理等等...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接