c – 从QGridLayout中删除小部件

前端之家收集整理的这篇文章主要介绍了c – 从QGridLayout中删除小部件前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我尝试从QGridLayout中的指定行中删除小部件,如下所示:
void delete_grid_row(QGridLayout *layout,int row)
{
    if (!layout || row < 0) return;

    for (int i = 0; i < layout->columnCount(); ++i) {
        QLayoutItem* item = layout->itemAtPosition(row,i);
        if (!item) continue;

        if (item->widget()) {
            layout->removeWidget(item->widget());
        } else {
            layout->removeItem(item);
        }
        delete item;
    }
}

但是当我打电话给它时,应用程序会在第一次迭代中使用SIGSEGV删除项目.有任何想法吗?

解决方法

注意:如果您只是寻找一个快速解决这个问题,那么只需使用下面提供的代码.如果您对网格布局中行列处理的背景和困难感兴趣,请继续阅读.

关于QGridLayout行和列

首先,请注意rowCount()和columnCount()返回内部分配的行和列数.例如,如果在新构造的网格布局上调用addWidget(widget,5,7),则行计数将为6,列计数将为8,并且除了行索引5之外的单元格的网格布局的所有单元格并且列索引7将为空,因此在GUI内不可见.

请注意,不可能从网格布局中删除这样的内部行或列.换句话说,网格布局的行和列计数因此总是只能增长,但不会缩小.

您可以做的是删除特定行或列的单元格的内容,这将有效地与删除行或列本身具有相同的效果.但是请注意,这不会更改任何行或列计数,也不会更改任何行或列索引.

清除行或列

那么一行或一列的内容怎么能被清除?这不幸也不像看起来那么容易.

首先,您需要考虑如果您只想从布局中删除小部件,或者您还希望将其删除.如果您仅从布局中删除小部件,则可以将它们重新放入不同的布局,或者手动给它们一个合理的几何体. (请注意,如果不这样做,这些小部件将只会在当前位置保持可见,这几乎绝对不是您想要的.)如果小部件也被删除,它们将从GUI中消失.下面提供的代码使用一个布尔参数来控制小部件删除.

接下来,我们必须考虑一个布局单元格不能只包含一个窗口小部件,而且还包含嵌套布局,其本身可以包含嵌套布局等等.我们还需要处理跨越多行和列的布局项.最后,还有一些行和列属性,如最小宽度和高度,不依赖于单元格内容,但仍然必须重置.

把它放在一起 – 代码

使用下面的removeRow()和removeColumn()函数从网格布局中删除一行或一列.

/**
 * Helper function. Removes all layout items within the given @a layout
 * which either span the given @a row or @a column. If @a deleteWidgets
 * is true,all concerned child widgets become not only removed from the
 * layout,but also deleted.
 */
void remove(QGridLayout *layout,int row,int column,bool deleteWidgets) {
    // We avoid usage of QGridLayout::itemAtPosition() here to improve performance.
    for (int i = layout->count() - 1; i >= 0; i--) {
        int r,c,rs,cs;
        layout->getItemPosition(i,&r,&c,&rs,&cs);
        if ((r <= row && r + rs - 1 >= row) || (c <= column && c + cs - 1 >= column)) {
            // This layout item is subject to deletion.
            QLayoutItem *item = layout->takeAt(i);
            if (deleteWidgets) {
                deleteChildWidgets(item);
            }
            delete item;
        }
    }
}

/**
 * Helper function. Deletes all child widgets of the given layout @a item.
 */
void deleteChildWidgets(QLayoutItem *item) {
    if (item->layout()) {
        // Process all child items recursively.
        for (int i = 0; i < item->layout()->count(); i++) {
            deleteChildWidgets(item->layout()->itemAt(i));
        }
    }
    delete item->widget();
}

/**
 * Removes all layout items on the given @a row from the given grid
 * @a layout. If @a deleteWidgets is true,all concerned child widgets
 * become not only removed from the layout,but also deleted. Note that
 * this function doesn't actually remove the row itself from the grid
 * layout,as this isn't possible (i.e. the rowCount() and row indices
 * will stay the same after this function has been called).
 */
void removeRow(QGridLayout *layout,bool deleteWidgets) {
    remove(layout,row,-1,deleteWidgets);
    layout->setRowMinimumHeight(row,0);
    layout->setRowStretch(row,0);
}

/**
 * Removes all layout items on the given @a column from the given grid
 * @a layout. If @a deleteWidgets is true,but also deleted. Note that
 * this function doesn't actually remove the column itself from the grid
 * layout,as this isn't possible (i.e. the columnCount() and column
 * indices will stay the same after this function has been called).
 */
void removeColumn(QGridLayout *layout,column,deleteWidgets);
    layout->setColumnMinimumWidth(column,0);
    layout->setColumnStretch(column,0);
}

猜你在找的C&C++相关文章