QT QStandardItemModel segfaulting

时间:2015-02-20 06:59:14

标签: c++ qt segmentation-fault

我对QT很新,我正在尝试从文本文件中获取一个列表并将其输出到QT中并且格式很好。

我设法在窗口上打印列表,但必须能够对其进行排序。

我现在设置了单选按钮,以便其中一个显示列表,另一个清除列表。

问题是,当我从列表切换到清除列表回到列表时,程序会出现段错误,我不明白为什么。

文件在这里。

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();
}

Clicking sort the first time

Switching Radio Button and clicking sort again

Switching Radio Button back and clicking sort again

感谢任何帮助,我在这里完全迷失了。

1 个答案:

答案 0 :(得分:1)

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);

- UPD ---

当您最初填充模型时,它会对wList中的项目拥有所有权。将模型项替换为空项时,它会从wList中删除初始项。在此之后,wList无效移动,因为它包含带有悬空指针的Wine结构。这就是为什么当你第二次尝试填充你的模型时,它会崩溃。