C++ 从QGridLayout中删除QWidgets

C++ 从QGridLayout中删除QWidgets,c++,qt,qwidget,qgridlayout,C++,Qt,Qwidget,Qgridlayout,我有一个QGridLayout,在这里我添加了我的自定义QWidgets 当我尝试删除它们时,它们应该从布局中删除(函数layout.count()返回0),但它们仍然显示在界面中,我可以与它们交互 这里是我添加小部件的方法: void MyClass::addCustomWidget(CustomWidget *_widget, int r, int c) { layout->addWidget(_widget, r, c); _widget->show(); }

我有一个
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();
}
void MyClass::clearLayout()
{
qDebug()计数();
int columns=layout->columnCount();
int rows=layout->rowCount();
int i=0;

对于(int j=0;j只需清除。您没有删除小部件。您只从布局中删除它们。从布局中删除意味着该控件将不再管理(调整大小/定位),但并不意味着小部件将被“删除”(以C++方式)。。此外,小部件不会被神奇地隐藏。从布局中删除后,您的小部件仍然保留在创建/管理它的小部件中。因此,此布局的所有者仍然将此小部件作为子部件(可见子部件)

你必须

  • 隐藏小部件,或者如果您确定它将不再使用

  • 使用“delete”关键字删除小部件


  • 另外,您不需要调用
    removeWidget(item->widget())
    removeItem(item)
    对于所有布局项目(即使是那些内部有小部件的项目)

    都足够了。您没有“删除”小部件。您只是从布局中删除了它们。从布局中删除意味着只有该小部件将不再受管理通过这个布局调整大小/位置,但并不意味着小部件将被“删除”(C++方式)。也不会被魔法隐藏。你的小部件从布局中删除后仍然在控件中创建/管理。所以这个布局的所有者仍然有这个小部件,如子(可见的子)。 你必须

  • 隐藏小部件,或者如果您确定它将不再使用

  • 使用“delete”关键字删除小部件

  • 另外,您不需要调用
    removeWidget(item->widget())
    removeItem(item)
    对于所有布局项目(即使是内部有小部件的项目)

    试试看

    QLayoutItem *child;
    while ((child = layout->takeAt(0)) != 0);
    
    是的。如果出于任何原因,它不起作用,您可以使用小部件或布局项的集合,每次添加小部件时都会更新这些小部件或布局项。然后删除集合上的循环并从布局中删除每个元素。

    尝试

    QLayoutItem *child;
    while ((child = layout->takeAt(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;
            }
        }
    }
    
    是的。如果出于任何原因,它不起作用,您可以使用小部件或布局项的集合,每次添加小部件时都会更新该集合。然后,要删除集合上的循环并从布局中删除每个元素,请执行以下操作。

    标题:
    
    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;
            }
        }
    }
    
    类网格:QGridLayout { 公众: 网格(QWidget*父节点); void addElement(QWidget*元素,int x,int y); 无效删除(整数x,整数y); 空心调整大小(整型宽度、整型高度); 无效清除(); 受保护的: 大小; }; void Grid::clear(){ 对于(int i=0;i
    标题:
    类网格:QGridLayout
    {
    公众:
    网格(QWidget*父节点);
    void addElement(QWidget*元素,int x,int y);
    无效删除(整数x,整数y);
    空心调整大小(整型宽度、整型高度);
    无效清除();
    受保护的:
    大小;
    };
    void Grid::clear(){
    
    对于(int i=0;i您还可以使用
    deleteLater()
    来避免维护子对象的问题 迭代期间的计数:

    for (int i = 0; i < gridLayout.count(); i++)
    {
       gridLayout.itemAt(i)->widget()->deleteLater();
    }
    
    for(int i=0;iwidget()->deleteLayout();
    }
    
    您还可以使用
    deleteLater()
    来避免维护子系统的问题 迭代期间的计数:

    for (int i = 0; i < gridLayout.count(); i++)
    {
       gridLayout.itemAt(i)->widget()->deleteLater();
    }
    
    for(int i=0;iwidget()->deleteLayout();
    }
    
    这些答案对我都不起作用。在我的情况下,我有几个对象,每个对象都有自己的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
    pv
    QChartView
    的派生类。我无法解释为什么其他答案不起作用,但我花了几个小时尝试不同的小部件和不同的方法来删除而不删除、组织等等。

    这些答案对我都不起作用在我的情况下,我有几个对象,每个对象都有自己的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
    pv
    QChartView
    的派生类。我无法解释为什么其他答案不起作用,但我花了几个小时尝试了不同的小部件和不同的删除方式,而没有删除、组织等。我的目的是从布局(不再显示)但将它们保留在内存中。在从布局中删除小部件之前,我尝试隐藏小部件(_widget.hide),谢谢。我的目的是从布局中删除小部件(不再显示),但将它们保留在内存中。我尝试隐藏小部件(_widget.hide)在我将它们从布局中删除并成功之前,谢谢。可能重复的可能重复的可能重复的感谢5年后尝试解决问题;)谢谢5年后尝试解决问题;)