【问题标题】:QT QStandardItemModel segfaultingQT QStandardItemModel segfaulting
【发布时间】:2015-02-20 06:59:14
【问题描述】:

我对 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

ma​​in.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

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

【问题讨论】:

  • 你的程序调试了吗?
  • 是的。它告诉我我有一个段错误,从那里我不知道该去哪里。第三张图片。
  • 我猜wList 没有你想象的那么大。
  • 我有一个直接打印到命令行的版本,它运行良好。只有当我尝试在 QT 中重新创建它时,我才遇到问题。我实际上并没有改变太多的代码。我只是在将内容打印到表格时遇到问题。
  • @djscrew 你逐行遍历你的程序之前它segfaults找出哪一行导致了segfault。然后查看变量的值以找出程序做错了什么。学习调试是学习编程的重要组成部分。

标签: c++ qt segmentation-fault


【解决方案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);

--更新--

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

【讨论】:

  • 尝试这个之后,没有任何改变。
  • 我检查了调试器,果然 wList 充满了悬空指针。感谢您的帮助,现在一切都按计划进行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多