不幸的是,我发现的这个问题的答案对我不起作用。我想我在某个地方犯了错误...
我想向QGridLayout添加内容:
int rows = 2;
int columns = 2;
for(int i=0; i<rows; ++i){
for(int j=0; j<columns; ++j){
QVBoxLayout *layout = new QVBoxLayout();
QComboBox *c1 = new QComboBox();
QComboBox *c2 = new QComboBox();
layout->addWidget(c1);
layout->addWidget(c2);
ui->gridLayout->addLayout(layout,i,j);
}
}
我现在想更改此QGridLayout的内容。 因此,我首先要删除此布局中已经存在的所有内容。 我试图为此工作编写一个函数:
我尝试了几种方法,但从未删除旧的组合框:
void VieSchedpp_Analyser::setLayout(int rows, int columns){
qDeleteAll(ui->gridLayout->children());
for(int i=0; i<rows; ++i){
for(int j=0; j<columns; ++j){
QVBoxLayout *layout = new QVBoxLayout();
QComboBox *c1 = new QComboBox();
QComboBox *c2 = new QComboBox();
layout->addWidget(c1);
layout->addWidget(c2);
ui->gridLayout->addLayout(layout,i,j);
}
}
}
或
void VieSchedpp_Analyser::setLayout(int rows, int columns){
while( ui->gridLayout->count() >0){
auto itm = ui->gridLayout->takeAt(0);
if(itm->widget()){
delete itm->widget();
}
if(itm->layout()){
delete itm->layout();
}
}
for(int i=0; i<rows; ++i){
for(int j=0; j<columns; ++j){
QVBoxLayout *layout = new QVBoxLayout();
QComboBox *c1 = new QComboBox();
QComboBox *c2 = new QComboBox();
layout->addWidget(c1);
layout->addWidget(c2);
ui->gridLayout->addLayout(layout,i,j);
}
}
}
答案 0 :(得分:2)
我花了一段时间来重现OP的问题,但最终我明白了:
嵌套布局使事情变得更加复杂。为解决此问题,应递归清除布局。
在玩这个游戏的时候,我对样本进行了很多诊断。这让我想起了
我在示例代码中将诊断信息保留为注释。 我的示例应用程序:
onActivityResult
输出:
#include <QtWidgets>
class Label: public QLabel {
public:
Label(const QString &text): QLabel(text) { }
virtual ~Label() { qDebug() << "Destroyed:" << this << text(); }
};
class VBoxLayout: public QVBoxLayout {
public:
VBoxLayout() = default;
virtual ~VBoxLayout() { qDebug() << "Destroyed:" << this; }
};
void clearLayout(QLayout &qGrid)
{
for (int i = qGrid.count(); i--;) {
QLayoutItem *pQLItem = qGrid.takeAt(i);
if (QWidget *pQWidget = pQLItem->widget()) {
#if 0 // diagnostics
qDebug()
<< dynamic_cast<QLabel*>(pQWidget)->text() << ".parent():"
<< pQWidget->parent();
#endif // 0
delete pQWidget;
delete pQLItem;
} else if (QLayout *pQLayout = pQLItem->layout()) {
clearLayout(*pQLayout);
delete pQLayout;
}
}
}
void fillLayout(QGridLayout &qGrid)
{
static unsigned id;
int w = 1 + qrand() % 3, h = 1 + qrand() % 3;
for (int y = 0; y < h; ++y) {
for (int x = 0; x < w; ++x) {
if (qrand() & 1) {
QVBoxLayout *pQVBox = new VBoxLayout();
pQVBox->addWidget(
new Label(QString("Label %1").arg(++id)));
pQVBox->addWidget(
new Label(QString("Label %1").arg(++id)));
qGrid.addLayout(pQVBox, y, x);
} else {
qGrid.addWidget(
new Label(QString("Label %1").arg(++id)),
y, x);
}
}
}
#if 0 // diagnostics
qDebug() << "qGrid.parent().children().count():"
<< dynamic_cast<QWidget*>(qGrid.parent())->children().count();
qDebug() << "qGrid.parent().children():"
<< dynamic_cast<QWidget*>(qGrid.parent())->children();
#endif // 0
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
// setup GUI
QWidget qWin;
qWin.setWindowTitle(QString::fromUtf8("Demo Delete from QGridLayout"));
QGridLayout qGrid;
qWin.setLayout(&qGrid);
qWin.show();
#if 0 // diagnostics
qDebug() << "qGrid.parent():" << &qWin;
#endif // 0
fillLayout(qGrid);
// install timer
QTimer qTimer;
qTimer.setInterval(10000 /* ms */);
QObject::connect(&qTimer, &QTimer::timeout,
[&]() { clearLayout(qGrid); fillLayout(qGrid); });
qTimer.start();
// runtime loop
return app.exec();
}
快照:
如果排除了Destroyed: QLabel(0x1df10113a30) "Label 11"
Destroyed: QLabel(0x1df10112c70) "Label 10"
Destroyed: QVBoxLayout(0x1df10110d10)
Destroyed: QLabel(0x1df100caa90) "Label 9"
Destroyed: QLabel(0x1df1010ae60) "Label 8"
Destroyed: QLabel(0x1df1010fc80) "Label 7"
Destroyed: QLabel(0x1df100ca810) "Label 6"
Destroyed: QLabel(0x1df1010dfa0) "Label 5"
Destroyed: QLabel(0x1df1010cd30) "Label 4"
Destroyed: QLabel(0x1df100ca9e0) "Label 3"
Destroyed: QVBoxLayout(0x1df101095a0)
Destroyed: QLabel(0x1df1010af40) "Label 2"
Destroyed: QLabel(0x1df10109f40) "Label 1"
Destroyed: QLabel(0x1df1010d5f0) "Label 22"
Destroyed: QLabel(0x1df1010c830) "Label 21"
Destroyed: QVBoxLayout(0x1df1010e450)
Destroyed: QLabel(0x1df1010e3b0) "Label 20"
Destroyed: QLabel(0x1df10111d60) "Label 19"
Destroyed: QLabel(0x1df1010f6f0) "Label 18"
Destroyed: QVBoxLayout(0x1df1010f4f0)
Destroyed: QLabel(0x1df101133d0) "Label 17"
Destroyed: QLabel(0x1df101117b0) "Label 16"
Destroyed: QVBoxLayout(0x1df101115b0)
Destroyed: QLabel(0x1df101144d0) "Label 15"
Destroyed: QLabel(0x1df1010a0b0) "Label 14"
Destroyed: QVBoxLayout(0x1df101130e0)
Destroyed: QLabel(0x1df100ca810) "Label 13"
Destroyed: QLabel(0x1df100f1310) "Label 12"
Destroyed: QVBoxLayout(0x1df101095a0)
Destroyed: QLabel(0x1df100f1310) "Label 23"
Destroyed: QLabel(0x1df1010b4f0) "Label 27"
Destroyed: QLabel(0x1df1010a0b0) "Label 26"
Destroyed: QVBoxLayout(0x1df101095a0)
Destroyed: QLabel(0x1df100d07e0) "Label 25"
Destroyed: QLabel(0x1df100f1310) "Label 24"
的递归调用行,则仅删除最顶层布局的窗口小部件,而不删除嵌套布局中的窗口小部件(尽管布局本身被删除/删除)。原因:这些后面的小部件仍然是父小部件的子代。 (我不知道这些小部件的父级布局已删除后如何处理。实际上,我试图防止这种情况在生产性软件中发生。)
要清除的快照快照:
我在Visual Studio 2013(Window 10 64位)中使用Qt 5.9.2编译了示例。
我也在cygwin64中尝试了类似的结果。
对于cygwin,我使用了以下项目文件:
clearLayout()
答案 1 :(得分:0)
您正在从ui->gridLayout_skyCoverage
删除项目,但新项目已添加到ui->gridLayout
。
更新
可能您应该删除项目本身,而不是其layout()
或widget()
(请参阅QLayout::takeAt)