QT QStandardItemModel 段错误
QT QStandardItemModel segfaulting
我是 QT 的新手,我正在尝试从文本文件中获取列表并将其以良好的格式输出到 QT 中。
我设法在 window 上打印了列表,但必须能够对其进行排序。
我现在设置了单选按钮,其中一个显示列表,另一个清除列表。
问题是,当我从列表切换到清除列表再回到列表时,程序出现段错误,我不明白为什么。
文件在这里。
winelist.cpp
#include "winelist.h"
#include "ui_winelist.h"
#include <QFile>
#include <QString>
#include <QStandardItemModel>
wineList::wineList(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::wineList)
{
ui->setupUi(this);
ui->ratingButton->setChecked(true);
fillList();
model->setHorizontalHeaderItem(0, new QStandardItem(QString("Wine Name")));
model->setHorizontalHeaderItem(1, new QStandardItem(QString("Vintage")));
model->setHorizontalHeaderItem(2, new QStandardItem(QString("Rating")));
model->setHorizontalHeaderItem(3, new QStandardItem(QString("Price")));
ui->listOutput->setModel(model);
}
wineList::~wineList()
{
delete ui;
}
void wineList::on_sortButton_clicked()
{
if( ui->ratingButton->isChecked())
{
for (int i = 0; i < 100; i++) {
model->setItem(i,0,wList[i].wineName);
model->setItem(i,1,wList[i].vintage);
model->setItem(i,2,wList[i].rating);
model->setItem(i,3,wList[i].price);
}
}
else
{
for(int i = 0; i < 100; i++) {
for(int j = 0; j < 4; j++) {
model->setItem(i, j, new QStandardItem(QString("")));
}
}
}
ui->listOutput->resizeColumnsToContents();
ui->listOutput->resizeRowsToContents();
}
void wineList::fillList()
{
Wine wine;
QString line;
QStringList lineElements;
QFile wineText(":/winelist.txt");
if (wineText.open(QIODevice::ReadOnly))
{
while ((line = line.fromUtf8(wineText.readLine())) != "")
{
lineElements = line.split(";");
lineElements[0].replace("\t", "");
lineElements[1].replace("\t", "");
wine.wineName = new QStandardItem(QString(lineElements.at(0)));
wine.vintage = new QStandardItem(QString(lineElements.at(1)));
wine.rating = new QStandardItem(QString::number(lineElements.at(2).toInt()));
wine.price = new QStandardItem(QString::number(lineElements.at(3).toInt()));
wList.append(wine);
}
}
wineText.close();
}
winelist.h
#ifndef WINELIST_H
#define WINELIST_H
#include <QMainWindow>
#include <QStandardItem>
#include <QStandardItemModel>
namespace Ui {
class wineList;
}
struct Wine {
QStandardItem* wineName;
QStandardItem* vintage;
QStandardItem* rating;
QStandardItem* price;
};
class wineList : public QMainWindow
{
Q_OBJECT
public:
explicit wineList(QWidget *parent = 0);
~wineList();
private slots:
void on_sortButton_clicked();
private:
Ui::wineList *ui;
QVarLengthArray<Wine> wList;
QStandardItemModel *model = new QStandardItemModel(100, 4, this);
void fillList();
void printList(QStandardItemModel *model);
};
#endif // WINELIST_H
main.cpp
#include "winelist.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
wineList w;
w.show();
return a.exec();
}
Switching Radio Button and clicking sort again
Switching Radio Button back and clicking sort again
感谢任何帮助,我完全迷失在这里。
在 on_sortButton_clicked
中,您试图从列表中读取数据,但没有进行任何范围检查。相反,您在那里硬编码了 100。
你应该重写这个:
for (int i = 0; i < 100; i++) {
model->setItem(i,0,wList[i].wineName);
对此:
for (int i = 0; i < wList.size(); i++) {
model->setItem(i,0,wList[i].wineName);
--更新---
当您最初填充模型时,它会获得 wList
中项目的所有权。当您将模型项替换为空项时,它会从 wList
中删除初始项。在此之后,您的 wList
无效移动,因为它包含 Wine
带有悬挂指针的结构。这就是为什么当您第二次尝试填充模型时,它会崩溃。
我是 QT 的新手,我正在尝试从文本文件中获取列表并将其以良好的格式输出到 QT 中。
我设法在 window 上打印了列表,但必须能够对其进行排序。
我现在设置了单选按钮,其中一个显示列表,另一个清除列表。
问题是,当我从列表切换到清除列表再回到列表时,程序出现段错误,我不明白为什么。
文件在这里。
winelist.cpp
#include "winelist.h"
#include "ui_winelist.h"
#include <QFile>
#include <QString>
#include <QStandardItemModel>
wineList::wineList(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::wineList)
{
ui->setupUi(this);
ui->ratingButton->setChecked(true);
fillList();
model->setHorizontalHeaderItem(0, new QStandardItem(QString("Wine Name")));
model->setHorizontalHeaderItem(1, new QStandardItem(QString("Vintage")));
model->setHorizontalHeaderItem(2, new QStandardItem(QString("Rating")));
model->setHorizontalHeaderItem(3, new QStandardItem(QString("Price")));
ui->listOutput->setModel(model);
}
wineList::~wineList()
{
delete ui;
}
void wineList::on_sortButton_clicked()
{
if( ui->ratingButton->isChecked())
{
for (int i = 0; i < 100; i++) {
model->setItem(i,0,wList[i].wineName);
model->setItem(i,1,wList[i].vintage);
model->setItem(i,2,wList[i].rating);
model->setItem(i,3,wList[i].price);
}
}
else
{
for(int i = 0; i < 100; i++) {
for(int j = 0; j < 4; j++) {
model->setItem(i, j, new QStandardItem(QString("")));
}
}
}
ui->listOutput->resizeColumnsToContents();
ui->listOutput->resizeRowsToContents();
}
void wineList::fillList()
{
Wine wine;
QString line;
QStringList lineElements;
QFile wineText(":/winelist.txt");
if (wineText.open(QIODevice::ReadOnly))
{
while ((line = line.fromUtf8(wineText.readLine())) != "")
{
lineElements = line.split(";");
lineElements[0].replace("\t", "");
lineElements[1].replace("\t", "");
wine.wineName = new QStandardItem(QString(lineElements.at(0)));
wine.vintage = new QStandardItem(QString(lineElements.at(1)));
wine.rating = new QStandardItem(QString::number(lineElements.at(2).toInt()));
wine.price = new QStandardItem(QString::number(lineElements.at(3).toInt()));
wList.append(wine);
}
}
wineText.close();
}
winelist.h
#ifndef WINELIST_H
#define WINELIST_H
#include <QMainWindow>
#include <QStandardItem>
#include <QStandardItemModel>
namespace Ui {
class wineList;
}
struct Wine {
QStandardItem* wineName;
QStandardItem* vintage;
QStandardItem* rating;
QStandardItem* price;
};
class wineList : public QMainWindow
{
Q_OBJECT
public:
explicit wineList(QWidget *parent = 0);
~wineList();
private slots:
void on_sortButton_clicked();
private:
Ui::wineList *ui;
QVarLengthArray<Wine> wList;
QStandardItemModel *model = new QStandardItemModel(100, 4, this);
void fillList();
void printList(QStandardItemModel *model);
};
#endif // WINELIST_H
main.cpp
#include "winelist.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
wineList w;
w.show();
return a.exec();
}
Switching Radio Button and clicking sort again
Switching Radio Button back and clicking sort again
感谢任何帮助,我完全迷失在这里。
在 on_sortButton_clicked
中,您试图从列表中读取数据,但没有进行任何范围检查。相反,您在那里硬编码了 100。
你应该重写这个:
for (int i = 0; i < 100; i++) {
model->setItem(i,0,wList[i].wineName);
对此:
for (int i = 0; i < wList.size(); i++) {
model->setItem(i,0,wList[i].wineName);
--更新---
当您最初填充模型时,它会获得 wList
中项目的所有权。当您将模型项替换为空项时,它会从 wList
中删除初始项。在此之后,您的 wList
无效移动,因为它包含 Wine
带有悬挂指针的结构。这就是为什么当您第二次尝试填充模型时,它会崩溃。