第二次运行时程序停止

时间:2018-04-07 06:27:38

标签: c++ qt qt5 qtabwidget

我正在使用Qt5制作图书馆管理软件。我已定义了打开和保存库并添加书籍的功能。

我最近在主窗口中添加了标签,因此像记事本++一样,我们可以同时使用不同的库。第一个库文件打开正常,但第二个库给我一个分段错误(使用调试器找到)

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QFileDialog>
#include <QTextStream>
#include "form.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    model.resize(1);

    model[0] = new QStandardItemModel(l.numOfBooks(), 3, this);
    model[0]->setHorizontalHeaderItem(0, new QStandardItem( QString("Name") ));
    model[0]->setHorizontalHeaderItem(1, new QStandardItem( QString("Author") ));
    model[0]->setHorizontalHeaderItem(2, new QStandardItem( QString("UID") ));

    ui->tableView->setModel(model[0]);
    model[0]->setRowCount(0);

    showMaximized();

    fileName.resize(0);

    ui->tabWidget->removeTab(1);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_actionAdd_Book_triggered()
{
    d = new Dialog(this);

    connect(d, SIGNAL(bookDetailsEntered(book&)), this, SLOT(onBookDetailsEntered(book&)));

    d->exec();
}

void MainWindow :: onBookDetailsEntered(book& b)
{
    d->close();
    delete d;

    l.addBook(b);
    model[ui->tabWidget->currentIndex()]->insertRow(model[ui->tabWidget->currentIndex()]->rowCount(QModelIndex()));

    QStandardItem *name = new QStandardItem(b.getName());
    model[ui->tabWidget->currentIndex()]->setItem(model[ui->tabWidget->currentIndex()]->rowCount() - 1, 0, name);

    QStandardItem *author = new QStandardItem(b.getAuthor());
    model[ui->tabWidget->currentIndex()]->setItem(model[ui->tabWidget->currentIndex()]->rowCount() - 1, 1, author);

    QStandardItem *uid = new QStandardItem(b.getUid());
    model[ui->tabWidget->currentIndex()]->setItem(model[ui->tabWidget->currentIndex()]->rowCount() - 1, 2, uid);

    ui->tableView->resizeColumnsToContents();
}

void MainWindow::on_actionSave_triggered()
{
    QString fn;

    if(fileName[ui->tabWidget->currentIndex()] == "")
        fn = QFileDialog::getSaveFileName(this, "Save");
    else
        fn = fileName[ui->tabWidget->currentIndex()];

    QFile file;

    if(fn.right(3) == ".lc")
    {
        file.setFileName(fn);
        if(!file.open(QFile::WriteOnly))
            QMessageBox :: warning(this, "Oops!", "Unable to open the file");
    }
    else
    {
        fn += ".lc";
        file.setFileName(fn);

        if(!file.open(QFile::WriteOnly))
            QMessageBox :: warning(this, "Oops!", "Unable to open the file");
    }

    //use tableview here
    QTextStream out(&file);

    for(int i = 0; i < model[ui->tabWidget->currentIndex()]->rowCount(); ++i)
    {
        QString s = "";

        QModelIndex index = model[ui->tabWidget->currentIndex()]->index(i, 0, QModelIndex());
        s += model[ui->tabWidget->currentIndex()]->data(index).toString();
        s += " ~ ";

        index = model[ui->tabWidget->currentIndex()]->index(i, 1, QModelIndex());
        s += model[ui->tabWidget->currentIndex()]->data(index).toString();
        s += " ~ ";

        index = model[ui->tabWidget->currentIndex()]->index(i, 2, QModelIndex());
        s += model[ui->tabWidget->currentIndex()]->data(index).toString();
        s += "\n";

        out << s;
    }

    file.flush();
    file.close();
}

void MainWindow::on_actionOpen_triggered()
{
    //ui->label->setText("");

    //model->removeRows(0, model->rowCount());

    QString fn = QFileDialog :: getOpenFileName(this, "Open");
    QFile file(fn);

    fn = fn.right(fn.length() - fn.lastIndexOf('/') - 1);

    if(ui->tabWidget->tabText(ui->tabWidget->currentIndex()) != "Unnamed")
    {
        ui->tabWidget->addTab(new Form(), fn);
        ui->tabWidget->setCurrentIndex(ui->tabWidget->count() - 1);
    }
    else
        ui->tabWidget->setTabText(ui->tabWidget->currentIndex(), fn);

    //resize arrays to fit things in

    fileName.resize(ui->tabWidget->count());
    fileName[ui->tabWidget->count() - 1] = fn;

    model.resize(ui->tabWidget->count());

    if(!file.open(QFile::ReadOnly))
    {
        QMessageBox :: warning(this, "Oops!", "File not open. Check if file exists");
        return;
    }

    //use table view here

    QTextStream in(&file);

    while(!in.atEnd())
    {
        QString s = in.readLine();

        int i;
        for(i = 0; s.at(i) != "~"; ++i);

        QString name = s.left(i - 1);

        for(i = name.length() + 3; s.at(i) != "~"; ++i);

        QString author = s.mid(name.length() + 3, (i - 1) - (name.length() + 3) );

        QString uid = s.right(s.length() - (i + 2));

        //display it
        model[ui->tabWidget->currentIndex()] -> insertRow(model[ui->tabWidget->currentIndex()]->rowCount(QModelIndex()));

        //name of the book
        QStandardItem* n = new QStandardItem(name);
        model[ui->tabWidget->currentIndex()]->setItem(model[ui->tabWidget->currentIndex()]->rowCount() - 1, 0, n);

        //author
        QStandardItem* a = new QStandardItem(author);
        model[ui->tabWidget->currentIndex()]->setItem(model[ui->tabWidget->currentIndex()]->rowCount() - 1, 1, a);

        //uid
        QStandardItem* u = new QStandardItem(uid);
        model[ui->tabWidget->currentIndex()]->setItem(model[ui->tabWidget->currentIndex()]->rowCount() - 1, 2, u);
    }

    file.close();
}


void MainWindow::on_actionName_triggered()
{
    ui->tableView->sortByColumn(0, Qt::AscendingOrder);
}

void MainWindow::on_actionAuthor_triggered()
{
    ui->tableView->sortByColumn(1, Qt::AscendingOrder);
}


void MainWindow::on_tabWidget_tabCloseRequested(int index)
{
    QMessageBox::StandardButton reply = QMessageBox :: warning(this, "Warning: ", "You will not ba able to get back details if you close without saving. Do you want to continue?",
                                                               QMessageBox :: Yes | QMessageBox :: No);

    if(reply == QMessageBox :: Yes)
        ui->tabWidget->removeTab(index);
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "library.h"
#include "dialog.h"
#include <QStandardItem>

using namespace std;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();


private slots:
    void on_actionAdd_Book_triggered();
    void onBookDetailsEntered(book& b);

    void on_actionSave_triggered();

    void on_actionOpen_triggered();
    void on_actionName_triggered();

    void on_actionAuthor_triggered();

    void on_tabWidget_tabCloseRequested(int index);

private:
    Ui::MainWindow *ui;
    library l;
    Dialog *d;
    vector <QStandardItemModel *>model;
    vector<QString> fileName;
};

#endif // MAINWINDOW_H

mainwindow.cpp第169行,即

model[ui->tabWidget->currentIndex()] -> insertRow(model[ui->tabWidget->currentIndex()]->rowCount(QModelIndex()));

给出this error

1 个答案:

答案 0 :(得分:1)

你有一个大小为1的std :: vector MainWindow :: model,你似乎正在尝试访问一个超出向量边界的索引(ui-> tabWidget-&gt; currentIndex()) 。 ui&gt; tabWidget和模型向量之间存在依赖关系,这可能导致此类索引问题。

重构你的程序时,我建议你考虑从QAbstractTableModel派生一个子类(看起来你的每本书都有相同的数据,所以表格似乎合适)。 您甚至可以使用预定义的QSqlTableModel类,它需要您使用sql驱动程序(sqlite可能最符合您的需求),但这可以避免您编写任何新代码以将数据保存到一个文件或从文件中加载它。