gpt4 book ai didi

c++ - 从 QGridLayout 中删除小部件

转载 作者:IT老高 更新时间:2023-10-28 23:11:21 26 4
gpt4 key购买 nike

我尝试从 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;
}
}

但是当我调用它时,应用程序在第一次迭代中因 delete item 上的 SIGSEGV 而崩溃。有什么想法吗?

最佳答案

简答:使用下面提供的代码

QGridLayout 中删除一行或一列(甚至单个单元格)是很棘手的。使用下面提供的代码。

长答案:深入了解 QGridLayout 细节

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

请注意,不幸的是不可能从网格布局中删除这样的内部行或列。换句话说,网格布局的行数和列数总是只能增加,不能减少。

可以做的是删除行或列的内容,这将有效地具有与删除行或列本身相同的视觉效果。但这当然意味着所有行数和列数以及索引将保持不变

那么如何清除行或列(或单元格)的内容呢?不幸的是,这也并不像看起来那么容易。

首先,您需要考虑是否只想从布局中删除小部件,或者是否还希望它们被删除。如果您只从布局中删除小部件,则必须在之后将它们放回不同的布局或手动给它们一个合理的几何形状。如果小部件也被删除,它们将从 GUI 中消失。提供的代码使用 bool 参数来控制小部件的删除。

接下来,你必须考虑一个布局单元格不仅可以包含一个小部件,还可以包含一个嵌套布局,它本身可以包含嵌套布局等等。您还需要处理跨越多行和多列的布局项。最后,还有一些行和列的属性,例如最小宽度和高度,它们不依赖于实际内容,但仍然需要注意。

代码

#include <QGridLayout>
#include <QWidget>

/**
* Utility class to remove the contents of a QGridLayout row, column or
* cell. If the deleteWidgets parameter is true, then the widgets become
* not only removed from the layout, but also deleted. Note that we won't
* actually remove any row or column itself from the layout, as this isn't
* possible. So the rowCount() and columnCount() will always stay the same,
* but the contents of the row, column or cell will be removed.
*/
class GridLayoutUtil {

public:

// Removes the contents of the given layout row.
static void removeRow(QGridLayout *layout, int row, bool deleteWidgets = true) {
remove(layout, row, -1, deleteWidgets);
layout->setRowMinimumHeight(row, 0);
layout->setRowStretch(row, 0);
}

// Removes the contents of the given layout column.
static void removeColumn(QGridLayout *layout, int column, bool deleteWidgets = true) {
remove(layout, -1, column, deleteWidgets);
layout->setColumnMinimumWidth(column, 0);
layout->setColumnStretch(column, 0);
}

// Removes the contents of the given layout cell.
static void removeCell(QGridLayout *layout, int row, int column, bool deleteWidgets = true) {
remove(layout, row, column, deleteWidgets);
}

private:

// Removes all layout items which span the given row and column.
static 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 (
(row == -1 || (r <= row && r + rs > row)) &&
(column == -1 || (c <= column && c + cs > column))) {
// This layout item is subject to deletion.
QLayoutItem *item = layout->takeAt(i);
if (deleteWidgets) {
deleteChildWidgets(item);
}
delete item;
}
}
}

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

关于c++ - 从 QGridLayout 中删除小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5395266/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com