QT Layout 添加不正确

QT Layout not adding properly

我目前正在通过制作一种“RecipeBook”应用程序来学习 Qt。它有一个功能,目前应该只将布局从 QMap 添加到我的主 QLayout。不幸的是,出现了上述错误:

添加最后一个布局时,大多数情况下都会发生这种情况,但这不是规则。我对这段代码做了很多实验,所以很抱歉它太乱了。当我启动 RefillRecipeLayout 函数时,语句是“while(i != endIterator)”,但它的行为相同。下面我向您发送我的代码:

mainwindow.cpp

void MainWindow::on_recalculateButton_clicked()
{
    currentRecipe.RefreshIngredientsInMap(deleteButtonToIngredientLayoutMap);
    RefillRecipeLayout();
}

void MainWindow::DeleteLayout(QLayout* layout)
{
    ClearLayout(layout);
    delete layout;
}

void MainWindow::ClearLayout(QLayout* layout)
{
    while (layout->count() != 0)
    {
        QLayoutItem* item = layout->takeAt(0);
        delete item->widget();
        delete item;
    }
}

void MainWindow::RefreshRecipeLayout()
{
   ClearLayout(recipeLayout);
}

void MainWindow::RefillRecipeLayout()
{
    ClearLayout(recipeLayout);
    int recipeCount= recipeLayout->count();
    int iCount=0;

    QMap<QPushButton*, QHBoxLayout*>::const_iterator i = deleteButtonToIngredientLayoutMap.constBegin();
    QMap<QPushButton*, QHBoxLayout*>::const_iterator endIterator = deleteButtonToIngredientLayoutMap.constEnd();
    int end = std::distance(i, endIterator);
        while (iCount < end)
        {
          QLayout* layout = i.value();
          int recipeCount = recipeLayout->count();
          auto isEmpty=recipeLayout->isEmpty();
          auto isEnabled = recipeLayout->isEnabled();
          bool exists = recipeLayout;
          recipeLayout->addLayout(layout);
          i++;
          iCount++;
        }
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QComboBox>
#include <QSpinBox>
#include <QTextEdit>
#include <QLabel>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QScrollArea>
#include <QScrollBar>
#include "recipe.h"
#include "ingredient.h"
#include <vector>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_addIngredient_clicked();

    void on_ExitButton_clicked();

    void on_recalculateButton_clicked();

private:
    Ui::MainWindow *ui;
    QMap<QPushButton*, QHBoxLayout*> deleteButtonToIngredientLayoutMap;
    QComboBox* ingredientUnitComboBox=nullptr;
    QSpinBox* ingredientAmountSpinBox=nullptr;
    QTextEdit* ingredientNameText=nullptr;
    QLabel* recipeAmountLabel=nullptr;
    QLabel* recipeNameLabel=nullptr;
    QComboBox* recipeUnitCBox=nullptr;
    QComboBox* newRecipeUnitCBox=nullptr;
    QScrollArea* scrollArea=nullptr;
    QVBoxLayout* recipeLayout=nullptr;
    QSpinBox* recalculateSpinBox=nullptr;
    QComboBox* recalculateUnitCBox=nullptr;

    void PrepareComboBox(QComboBox* comboBox);
    void DeleteIngredient();
    void DeleteLayout(QLayout* layout);
    void ClearLayout(QLayout* layout);
    void RefillRecipeLayout();
    Unit GetUnitFromCBox(QComboBox* comboBox);
    void RefreshRecipeLayout();

};
#endif // MAINWINDOW_H

来自 Recipe.cpp 的 RefreshIngredientsFunction(据我所知效果很好,我检查了断点)

void Recipe::RefreshIngredientsInMap(QMap<QPushButton*, QHBoxLayout*> OtherMap)
{


    QMap<QPushButton*, QHBoxLayout*>::const_iterator i = OtherMap.constBegin();
    QMap<QPushButton*, QHBoxLayout*>::const_iterator iteratorEnd = OtherMap.constEnd();
    int count=0;
    while (i != iteratorEnd)
    {
      QHBoxLayout* ingredientLayout=new QHBoxLayout();
      QHBoxLayout* layout = i.value();
      int end = std::distance(OtherMap.constBegin(), OtherMap.constEnd());
      int currentItemIndex=0;
      while(layout->count()>0)
      {
          QWidget* widget = layout->takeAt(0)->widget();

          if (QSpinBox* spinBox = qobject_cast<QSpinBox*>(widget))
              spinBox->setValue(13);

          ingredientLayout->addWidget(widget);



          currentItemIndex++;
      }
      delete layout;
      OtherMap.insert(i.key(), ingredientLayout);
      i++;
      count++;

    }
}

除了一些代码风格问题(不相关的调试行,不要在您的

中命名迭代器“i”)
void Recipe::RefreshIngredientsInMap(QMap<QPushButton*, QHBoxLayout*> OtherMap)

您正在复制地图。然后你试图通过删除一些布局并插入其他布局来修改它的内容。

delete layout;
OtherMap.insert(i.key(), ingredientLayout);

delete 操作破坏了您的地图指向的对象,然后在 RefreshIngredientsInMap returns 之后,原始地图指向被破坏的对象,因为插入是在一份。