问题描述
我有这样一个界面,红框里是一个widget对象,这些对象全部加在gridlayout布局中,设定布局格式为每行8个对象。
然后我选择除了最后一个之外的对象进行删除,接下来再去添加一个对象,就会出现这种重叠的情况。但是如果删除的是最后一个对象再去添加新的,就不会出现这种问题。打印了下addwidget的坐标传参也是正确的,但是在界面上显示出现问题,所以合理怀疑不是代码逻辑的问题,而是gridlayout内部布局的问题。
出错原因
因为gridlayout的布局特性,remove掉前面的widget,但是他的那个占位还是存在的。
像这样,虽然我删除掉了一个button,但是占位依然存在,所以即使逻辑上我们传入的坐标参数是正确的,但是在界面上看还是和最后一个widget重合了,但删除最后一个对象不会出现这种问题。
解决方法
我们需要在删除后将所有对象全部重排一次。我定义了一个QVector类型的数据将这些对象统一管理,然后在删除对象后再遍历QVector,将里面的对象重新按照位置顺序加入到gridlayout中,问题解决。代码如下:
QVector<u_do*> uDOWidgets;
// 2024.4.23 mr: 添加u_do.ui的槽函数
void MainWindow::addDO()
{
u_do_create *u_do_dialog = new u_do_create(card, this);
int ret = u_do_dialog->exec();
if(ret == QDialog::Accepted){
u_do *uDOWidget = new u_do(u_do_dialog->GetDO(), this);
int i = u_do_dialog->getDONum(); // 获取u_do_create.ui中输入的轴序号
uDOWidget->modLabelDONum(i); // 赋值do序号
uDOWidget->modLabelDOName(u_do_dialog->getDOName());// 赋值u_do_create.ui中输入的do名称
ui->comboBox_do->addItem(QString::number(i)); // combobox的下拉菜单中加入输入的值
uDOWidgets.append(uDOWidget);
int num = uDOWidgets.size() - 1;
int x = num/8;
int y = num%8;
ui->gridLayout_do->addWidget(uDOWidget, x, y);
delete u_do_dialog;
}
}
// 2024.4.24 mr: 删除u_do.ui
void MainWindow::deleteDO()
{
QString selectedText = ui->comboBox_do->currentText();
int j = selectedText.toInt(); // 获取combobox输入的值
int a = ui->comboBox_do->findText(selectedText); // 获取该值对应的索引值
for(int i = 0; i < uDOWidgets.size(); ++i){ // 查找该值对应的widget
if(uDOWidgets[i]->getLabelDONum() == j){
ui->gridLayout_do->removeWidget(uDOWidgets[i]);
delete uDOWidgets[i]; // 删除widget
uDOWidgets.removeAt(i);
for(int tofront = 0; tofront < uDOWidgets.size(); ++tofront){ // 全部重排
int x = tofront/8;
int y = tofront%8;
ui->gridLayout_do->addWidget(uDOWidgets[tofront], x, y);
}
ui->comboBox_do->removeItem(a); // 在combobox下拉框中删除该值
break;
}
}
}