QTableView output save as .csv or .txt
Asked Answered
V

3

11

I wrote the below code for a qt gui to view the query output in a QTableView(Model oriented). now i want to save this output as a .csv or .txt file. There were suggestions to use QTableWidget(Item oriented) but I would like to stick to the model based approach.

void MainWindow::on_pushButton_clicked()
{
db = QSqlDatabase::addDatabase("QOCI");
db.setHostName("host");
db.setDatabaseName("db");
db.setUserName("uid");
db.setPassword("pw");
db.setPort(port);

QString MyQuery = ui->lineEdit->text();

if (db.open())
{
    qDebug()<<QDateTime::currentDateTime()<<"QUERY DONE SUCCESSFULLY ";

    this->model=new QSqlQueryModel();
    model->setQuery(MyQuery);
    ui->tableView->setModel(model);

}
else
{
    qDebug()<<QDateTime::currentDateTime()<<"YOU FORGOT THE QUERY "<<db.lastError().text();
}

}

any guidelines ???

Vevine answered 8/12, 2014 at 7:8 Comment(0)
C
15

You may customize it according to your actual needs:

// [Collect model data to QString]
QString textData;
int rows = model->rowCount();
int columns = model->columnCount();

for (int i = 0; i < rows; i++) {
    for (int j = 0; j < columns; j++) {

            textData += model->data(model->index(i,j)).toString();
            textData += ", "      // for .csv file format
    }
    textData += "\n";             // (optional: for new line segmentation)
}

// [Save to file] (header file <QFile> needed)
// .csv
QFile csvFile("test.csv");    
if(csvFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {

    QTextStream out(&csvFile);
    out << textData;

    csvFile.close();
} 

// .txt
QFile txtFile("test.txt");    
if(txtFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {

    QTextStream out(&txtFile);
    out << textData;

    txtFile.close();
} 
Crankcase answered 8/12, 2014 at 7:22 Comment(7)
thank you for providing with this thought process, i tried to use this but it threw some errors during build time--- /usr/local/Trolltech/Qt-4.8.4/include/QtGui/qwidget.h:812: error: ‘QWidgetData* QWidget::data’ is private /home/aj/MY_QT_WORK/table_test/mainwindow.cpp:62: error: within this context /home/aj/MY_QT_WORK/table_test/mainwindow.cpp:62: error: invalid operands of types ‘QWidgetData*’ and ‘const char [2]’ to binary ‘operator+’ /home/aj/MY_QT_WORK/table_test/mainwindow.cpp:62: error: in evaluation of ‘operator+=(class QWidgetData*, const char [2])’Vevine
@AmarjitBiswas There were some syntax errors, and I've just corrected them. Please try the latest update.Crankcase
is the reverse also possible ?? that is using this .csv or .txt to populate a QTableView ??? any code-snippet / documentation-link will be very helpful. thanks again.Vevine
@AmarjitBiswas It's of course possible, but you have to "parse" the file no matter it's .csv or .txt. In other words, you have to determine the mapping methods of sequential data (.csv file for example) to your data model of QTableView. I would suggest you ask a new question and specify your needs, since the reverse approach would require you determine the file format first. Otherwise, it will be too board to answer.Crankcase
@AmarjitBiswas Ehh... I just found you have asked a similar question here, does that make any difference?Crankcase
actually my previous plan was to directly import to sqlite3 database but since sqlite3 .dot-commands can not be directly integrated to qt-c++ I am trying to follow a long process. for my purpose speed of execution doesnt matter, so i am thinking to use .csv or .txt files to keep copies of retrieved data and then use a scheduler to keep them loading in the sqlite database.Vevine
i posted my doubts in a separate question as suggested, #27354700 thank you...Vevine
H
5

You can save your model to a text file by :

QFile f( "table.txt" );
if( f.open( QIODevice::WriteOnly ) )
{
    QTextStream ts( &f );
    QStringList strList;
    for (int i=0; i<model->rowCount(); i++)
    {
        strList.clear();

        for (int j=0; j<model->columnCount(); j++)
            strList << model->data(model->index(i,j)).toString();

        ts << strList.join(" ") + "\n";
    }
    f.close();
}

Here the model data are saved one row in each line separated by space. If you want to separate them by some other character like comma you can just replace the parameter on the join like :

ts << strList.join(",") + "\n";
Headwards answered 8/12, 2014 at 7:43 Comment(0)
E
5

here is a way to export a qtableview to a csv, including the column names using qt

   void staticmethods::exportTableViewToCSV(QTableView *table) {
            QString filters("CSV files (*.csv);;All files (*.*)");
            QString defaultFilter("CSV files (*.csv)");
            QString fileName = QFileDialog::getSaveFileName(0, "Save file", QCoreApplication::applicationDirPath(),
                               filters, &defaultFilter);
            QFile file(fileName);

            QAbstractItemModel *model =  table->model();
            if (file.open(QFile::WriteOnly | QFile::Truncate)) {
                QTextStream data(&file);
                QStringList strList;
                for (int i = 0; i < model->columnCount(); i++) {
                    if (model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString().length() > 0)
                        strList.append("\"" + model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString() + "\"");
                    else
                        strList.append("");
                }
                data << strList.join(";") << "\n";
                for (int i = 0; i < model->rowCount(); i++) {
                    strList.clear();
                    for (int j = 0; j < model->columnCount(); j++) {

                        if (model->data(model->index(i, j)).toString().length() > 0)
                            strList.append("\"" + model->data(model->index(i, j)).toString() + "\"");
                        else
                            strList.append("");
                    }
                    data << strList.join(";") + "\n";
                }
                file.close();
            }

        }
Enstatite answered 15/9, 2017 at 9:49 Comment(3)
Just to note that although this calls its output .csv, the separator it uses is ";"...Ehrman
The output csv file merge all columns of one row in one cell, but what i expexted is each column occupys one cell, so i modify above code by replacing data << strList.join(";") << "\n"; with data << strList.join(",") << "\n";.Exasperation
I tried this code for export some datas coming from serial port. It works well but all datas shown on first row. How can I add tab for jump to next culumn. Here is question I asked. But I couldnt find solution.Pertussis

© 2022 - 2024 — McMap. All rights reserved.