简体   繁体   English

从 QGridLayout 中删除 QWidgets

[英]Removing QWidgets from a QGridLayout

I have a QGridLayout where I add my custom QWidgets .我有一个QGridLayout ,我在其中添加了我的自定义QWidgets

When I try to delete all of them they are supposedly removed from the layout (as the function layout.count() returns 0) but they are still shown in the interface and I can interact with them.当我尝试删除所有它们时,它们应该从布局中删除(因为函数layout.count()返回 0)但它们仍然显示在界面中,我可以与它们交互。

Here you have the way I add widgets:在这里,您可以使用我添加小部件的方式:

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

And here the way I delete them:这里是我删除它们的方式:

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();
}

Any kind of help or tip to delete items/widgets correctly from a QGridLayout?从 QGridLayout 正确删除项目/小部件的任何帮助或提示?

PD : I have seen on the internet that a lot of people deletes the widget directly (delete _widget) after removing them from the layout. PD:我在网上看到很多人在从布局中删除小部件后直接删除小部件(删除_widget)。 In my case it is not possible as I need to mantain that widgets in memory.就我而言,这是不可能的,因为我需要在内存中维护这些小部件。

Just to be clear.只是要清楚。 You didn't "delete" the widgets.您没有“删除”小部件。 You only removed them from layout.您只是从布局中删除了它们。 Removing from layout means only that widget will be no more managed (resized/positioned) by this layout BUT it doesn't mean that widget will be "deleted" (in C++ way).从布局中删除仅意味着小部件将不再由该布局管理(调整大小/定位),但这并不意味着小部件将被“删除”(以 C++ 方式)。 Also widget won't be magically hidden.小部件也不会被神奇地隐藏。 Your widget after removing from layout still leaves in widget it was created / managed in. So owner of this layout still has this widget as child (visible child).从布局中移除后,您的小部件仍保留在其创建/管理的小部件中。因此,此布局的所有者仍将此小部件作为子部件(可见子部件)。

You have to你必须

  1. hide widget or if you're sure it will not be used anymore隐藏小部件,或者如果您确定它不会再被使用

  2. delete widget with "delete" keyword使用“删除”关键字删除小部件

Also you don't need to call removeWidget(item->widget()) ;你也不需要调用removeWidget(item->widget()) removeItem(item) will be enough for all layout items (even those with widget inside) removeItem(item)足以用于所有布局项目(即使是那些带有小部件的项目)

Try尝试

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

It is supposed to be safe .应该是安全的 If for any reasons it doesn't work, you can use a collection of widgets or layoutitems, which is updated every time you add a widget.如果由于任何原因它不起作用,您可以使用小部件或布局项的集合,每次添加小部件时都会更新。 Then to delete you loop on the collection and remove each element from the layout.然后删除您在集合上循环并从布局中删除每个元素。

You can also use deleteLater() to avoid issue with maintaining child count during iterations:您还可以使用deleteLater()来避免在迭代期间维护子计数的问题:

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

None of these answers worked for me.这些答案都不适合我。 In my situation, I have several object each with their own QChartView.在我的情况下,我有几个对象,每个对象都有自己的 QChartView。 The idea is that the user selects which object they want to view and a common area central in the main window is updated with the QChartView of the user-selected object.这个想法是用户选择他们想要查看的对象,主窗口中央的公共区域用用户选择的对象的 QChartView 更新。 This should have been straightforward, simply remove the widget from the chart area, add a new one.这应该很简单,只需从图表区域中删除小部件,添加一个新小部件即可。 What ended up working for me was this:最终对我有用的是:

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);

Where mPlotArea is a QFrame and pv is a derived class of QChartView .其中mPlotAreaQFramepvQChartView的派生类。 I can't explain why the other answers did not worked, but I spent a couple of hours trying different widgets and different ways of removing without deleting, organizing, etc...我无法解释为什么其他答案不起作用,但我花了几个小时尝试不同的小部件和不同的删除方式而不删除,组织等......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM