Read and write to a file from a QTableView

10k views Asked by At

How can I read and write to a text file date enter to a QTableView?

This is what I have but I would like to save the data when it is added to the table and of course be able to read it back when the application is reopened. Is there any tutorial I can refer to?

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

    model = new QStandardItemModel();
    model->setRowCount(0);
    ui->tableView->setModel(model);
}

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

void MainWindow::on_pushButton_clicked()
{
    QStandardItem *userName = new QStandardItem(ui->lineEdit_Name->text());
    QStandardItem *userNumber = new QStandardItem(ui->lineEdit_Number->text());

    QList<QStandardItem*> row;
    row <<userName << userNumber;

    model->appendRow(row);
}

Thanks a lot

EDIT --------------------------------

This is what worked for me:

Add Function:

 void MainWindow::on_pushButto_Add_clicked() {
     QStandardItem *userInput = new QStandardItem(ui->lineEdit->text());
     QStandardItem *userInput2= new QStandardItem(ui->lineEdit_2->text());

     QList<QStandardItem*> row;
     row <<userInput << userInput2;

     model->appendRow(row); 
}

Save Function:

void MainWindow::on_pushButton_Save_clicked()
{
    QFile file("C:/Users/UserName/Practicing/Resources_Files/someFile.bin");

     if (file.open(QIODevice::WriteOnly))
     {
         QDataStream stream(&file);
         qint32 n = model->rowCount();
         qint32 m = model->columnCount();
         stream << n << m;

         for (int i=0; i<n; ++i)
         {
          for (int j=0; j<m; j++)
            {
              model->item(i,j)->write(stream);
            }
          }
        file.close();
      }
}

Load Function:

void MainWindow::on_pushButton_Load_clicked()
{

    QFile file("C:/Users/UserName/Practicing/Resources_Files/someFile.bin");
    if (file.open(QIODevice::ReadOnly))
    {
       QDataStream stream(&file);
        qint32 n, m;
        stream >> n >> m;
        model->setRowCount(n);
        model->setColumnCount(m);

        for (int i = 0; i < n ; ++i) {
               for (int j = 0; j < m; j++) {
                   QStandardItem *item = new QStandardItem;
                   item->read(stream);
                   model->setItem(i, j, item);
               }
           }

     file.close();
    }
}
3

There are 3 answers

11
Marek R On BEST ANSWER
QFile file("somefile.bin");

if (file.open(QIODevice::WriteOnly)) {
    QDataStream stream(&file);
    stream << *(model->invisibleRootItem());
    file.close();
}

http://qt-project.org/doc/qt-5.0/qtgui/qstandarditemmodel.html#invisibleRootItem


Edit:

Here is correction (I've checked that it works).

void MainWindow::save()
{
    QFile file("somefile.bin");
    if (file.open(QIODevice::WriteOnly)) {
        QDataStream stream(&file);
        qint32 n(model->rowCount()), m(model->columnCount());
        stream << n << m;

        for (int i=0; i<n; ++i)
            for (int j=0; j<m; j++)
                model->item(i,j)->write(stream);
        file.close();
    }
}

void MainWindow::load()
{
    QFile file("somefile.bin");
    if (file.open(QIODevice::ReadOnly)) {
        QDataStream stream(&file);
        qint32 n, m;
        stream >> n >> m;

        model->setRowCount(n);
        model->setColumnCount(m);
        for (int i=0; i<n; ++i)
            for (int j=0; j<m; j++)
                model->item(i,j)->read(stream);
        file.close();
    }
}
0
Dimitry Ernot On

You can browse your model row by row, column by column and fill a file with a format like CSV (a row by line and columns separated by coma or tabs).

But, I don't think that is a good idea to modify the file when an item has changed. You should write the file when your application is closed.

1
Liju G. Chacko On

model->item(i,j)->write(stream); will lead to segmentation fault if item(i,j) is empty. Assign some dummy value like whitespace in empty cells.