【问题标题】:The program stops when running the second time [closed]程序在第二次运行时停止[关闭]
【发布时间】:2023-03-09 03:03:01
【问题描述】:

我正在使用 Qt5 制作图书馆管理软件。我已经定义了打开和保存图书馆以及添加书籍的函数。

我最近在我的主窗口中添加了选项卡,以便像 notepad++ 一样,我们可以同时使用不同的库。第一个库文件打开正常,但第二个给我一个分段错误(使用调试器发现)

主窗口.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);
}

主窗口.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

【问题讨论】:

  • 你可以显示完整的错误信息。
  • @eyllanesc 再次感谢您的帮助。我已经用消息的屏幕截图更新了问题
  • 该错误消息是因为您正在访问您没有保留的内存,例如检查模型大小是否大于 currentIndex() 值,或者保存在 currentIndex( ) 模型内的位置被初始化,原因有很多,解决方法会发现它调试。
  • 我在第 141 行调整了模型 be4 的大小:model.resize(ui->tabWidget->count()); @ellyanesc
  • 假设您有 5 个 QStandardItemModel,并且您按照评论指示更改大小,新职位填充了哪些 QStandardItemModel? QStandardItemModel 为 null,并且您想使用 insertRow 方法将 QStandardItemModel 设为 null。你觉得对吗?如果要更改 QVector 的大小,还必须为新位置创建新模型

标签: c++ qt qt5 qtabwidget


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2019-08-15
    • 1970-01-01
    • 2012-07-12
    • 2019-07-07
    • 1970-01-01
    • 1970-01-01
    • 2014-07-28
    • 1970-01-01
    • 2022-01-05
    相关资源
    最近更新 更多