Faced with one problem. I have a table in which by pressing the buttons you can add, insert between existing lines and delete lines. When all the lines are deleted and I press the delete button again, the program crashes.

And the same with the insert button. I can not fix the error. I understand that there is an error in the code, but I don’t know how to implement it differently. I tried to prescribe restrictions, nothing happened either. I would be grateful for the help! Here is my full code:

Mainwindow.h file

#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "mymodel.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void on_pushButton_clicked(); void on_pushButton_2_clicked(); void on_pushButton_3_clicked(); private: Ui::MainWindow *ui; MyModel *Model; }; #endif // MAINWINDOW_H 

File mymodel.h

 #ifndef MYMODEL_H #define MYMODEL_H #include <QAbstractTableModel> #include <QVector> #include "sport.h" class MyModel : public QAbstractTableModel { Q_OBJECT public: explicit MyModel(QObject *parent = nullptr); int rowCount(const QModelIndex &parent = QModelIndex()) const ; int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole); Qt::ItemFlags flags(const QModelIndex & index) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; bool insertRows(int row, int count, const QModelIndex & parent = QModelIndex()); bool removeRows(int row, int count, const QModelIndex & parent = QModelIndex()); signals: // void editCompleted(const QString &); public slots: private: QVector<Sport> GridData; }; #endif // MYMODEL_H 

File sport.h

 #ifndef SPORT_H #define SPORT_H #include <QString> class Sport { public: Sport (); Sport (QString name, QString code); Sport (const Sport& v); Sport& operator= (const Sport&); QString name () const; QString code () const; float ball () const; int mesto () const; void setName (QString name); void setCode (QString code); void setMesto (int m); void setBall (float b); private: QString Name, Code; float Ball; int Mesto; }; #endif // SPORT_H 

Mainwindow.cpp file

 #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); Model = new MyModel; ui->tableView->setModel(Model); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { //add int row = Model->rowCount(); Model->insertRows(row, 1); QModelIndex in = Model->index(row, 1); ui->tableView->setCurrentIndex(in); ui->tableView->edit(in); } void MainWindow::on_pushButton_2_clicked() { //insert int row = ui->tableView->currentIndex().row(); Model->insertRows(row, 1); QModelIndex in = Model->index(row, 1); ui->tableView->setCurrentIndex(in); } void MainWindow::on_pushButton_3_clicked() { //delete Model->removeRows(ui->tableView->currentIndex().row(),1); } 

Mymodel.cpp file

 #include "mymodel.h" MyModel::MyModel(QObject *parent) : QAbstractTableModel(parent) { GridData.resize(1); } int MyModel::rowCount(const QModelIndex &parent) const { return GridData.size(); } int MyModel::columnCount(const QModelIndex &parent) const { return 4; } QVariant MyModel::data(const QModelIndex &index, int role) const { if (role == Qt::DisplayRole) { switch (index.column()) { case 0: return GridData[index.row()].name(); case 1: return GridData[index.row()].code(); case 2: return GridData[index.row()].ball(); case 3: return GridData[index.row()].mesto(); default: break; } } return QVariant(); } QVariant MyModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { switch (section) { case 0: return QVariant("Фамилия участника"); case 1: return QVariant("Код команды"); case 2: return QVariant("Количество балов"); case 3: return QVariant("Место в итоге"); default: break; } } return QVariant(); } bool MyModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (role == Qt::EditRole) { //save value from editor to member m_gridData // m_gridData[index.row()][index.column()] = value.toString(); switch (index.column()) { case 0: GridData[index.row()].setName(value.toString()); break; case 1: GridData[index.row()].setCode(value.toString()); break; case 2: GridData[index.row()].setBall(value.toInt()); break; case 3: GridData[index.row()].setMesto(value.toInt()); break; } } return true; } Qt::ItemFlags MyModel::flags(const QModelIndex &index) const { return Qt::ItemIsEditable | QAbstractTableModel::flags(index); } bool MyModel::insertRows(int row, int count, const QModelIndex &parent) { beginInsertRows(parent,row, row + count - 1); GridData.insert(row, count, Sport()); endInsertRows(); return true; } bool MyModel::removeRows(int row, int count, const QModelIndex &parent) { beginRemoveRows(parent,row, row + count - 1); GridData.remove(row, count); endRemoveRows(); return true; } 

Sport.cpp file

 #include "sport.h" Sport::Sport(): Ball(0.0), Mesto(0) { } Sport::Sport(QString name, QString code): Name(name), Code(code), Ball(0.0), Mesto(0) { } Sport::Sport(const Sport &v) { this->Name = v.Name; this->Code = v.Code; this->Ball = v.Ball; this->Mesto = v.Mesto; } Sport &Sport::operator =(const Sport &v) { this->Name = v.Name; this->Code = v.Code; this->Ball = v.Ball; this->Mesto = v.Mesto; return *this; } QString Sport::name() const { return Name; } QString Sport::code() const { return Code; } float Sport::ball() const { return Ball; } int Sport::mesto() const { return Mesto; } void Sport::setName(QString name) { this->Name = name; } void Sport::setCode(QString code) { this->Code = code; } void Sport::setBall(float b) { this->Ball = b; } void Sport::setMesto(int m) { this->Mesto = m; } 
  • one
    There is a lot of code and there is no desire to dig into it, it is better to leave a minimal, self-sufficient and reproducible example in the question. Когда все строки удалены и я снова нажимаю на кнопку удалить, то программа вылетает. ? Do not press the button when the table is empty - block the delete button ( setEnabled(false) ) when the table is empty, optionally. And in the removal method, check that the view / model is not empty. Ps. in such cases, use the debugger or throw a line output to the console - to determine the location of the crash - gil9red
  • Thank. (setEnabled (false)) I use. But I can’t pick the exact condition so that when the table is empty, the button is not active, and when rows are added again, it is active again. I always get blocked after one click .. - EgaNator
  • In the MainWindow, make the updateStates method, list the conditions for your widgets in it. For example, for a button it will be button->setEnabled(Model->rowCount()) . Call this function in the constructor, in the add and remove method. In general, in places that can change the state of the widget. Another option is to pick up the necessary signals and update them: doc.qt.io/qt-5/qabstractitemmodel.html#rowsInserted - gil9red
  • Thank you very much! I'll try! - EgaNator
  • one
    Add to the answer what you did to prevent the question from hanging without an answer :) - gil9red

1 answer 1

Here is)

 void MainWindow::on_pushButton_clicked() { //add int row = Model->rowCount(); Model->insertRows(row, 1); QModelIndex in = Model->index(row, 1); ui->tableView->setCurrentIndex(in); ui->tableView->edit(in); ui->pushButton_3->setEnabled(Model->rowCount()); ui->pushButton_2->setEnabled(Model->rowCount()); } void MainWindow::on_pushButton_2_clicked() { //insert int row = ui->tableView->currentIndex().row(); Model->insertRows(row, 1); QModelIndex in = Model->index(row, 1); ui->tableView->setCurrentIndex(in); } void MainWindow::on_pushButton_3_clicked() { //delete Model->removeRows(ui->tableView->currentIndex().row(), 1); ui->pushButton_3->setEnabled(Model->rowCount()); ui->pushButton_2->setEnabled(Model->rowCount()); }