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 之后,原始地图指向被破坏的对象,因为插入是在一份。
我目前正在通过制作一种“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 之后,原始地图指向被破坏的对象,因为插入是在一份。