Search code examples
qtqtableviewqfilecsv

Read and view tab-delimited txt files in Qt C++ using QTableView


I need some general advice to point me in the correct direction of solving this problem: I have a .txt file with table data like the following:

Time    Pin
11:00   EIO4
12:55   EIO6
16:40   EIO4
20:10   EIO3

etc......

I need to be able to parse this .txt file. Then I need to display this table in Qt (perhaps in a QTableView).

I have looked into using QTableView, and it appears I pass a QAbstractItemModel* to the QTableView using QTableView::setModel(QAbstractItemModel* model), after which my QTableView will display whatever data is in the QAbstractItemModel (right?).

If that last paragraph was logical, then my next question is how do I construct a QAbstractItemModel using my .txt file? I don't see any functions in the documentation that do this? (Note: someone suggested creating a QStandardItemModel)

(Note, this paragraph is no longer relevant) QModelIndex createIndex(int row, int column, void* ptr) appears to have something to do with this, maybe? Maybe this creates a QModelIndex that can be passed to the QAbstractItemModel using QAbstractItemModel::insertRow(QModelIndex)? However I still don't know how to make these QModelIndex objects have anything to do with my .txt data.

QStandardItemModel documentation says

When you want a list or tree, you typically create an empty QStandardItemModel and use appendRow() to add items to the model, and item() to access an item. If your model represents a table, you typically pass the dimensions of the table to the QStandardItemModel constructor and use setItem() to position items into the table. You can also use setRowCount() and setColumnCount() to alter the dimensions of the model. To insert items, use insertRow() or insertColumn(), and to remove items, use removeRow() or removeColumn().

These functions that "add rows" take QList<QStandardItem*>'s as arguments, so I need to create QLists that each contain pointers QStandardItems that contain each cell's data?

So I will use

void QStandardItemModel::insertRow(int row, const QList<QStandardItem *> & items)

http://doc.qt.io/qt-5/qstandarditemmodel.html#insertRow

Along with an argument QList<QStandardItem*> generated by repeated calls of "<<" passing QStandardItem* pointers to an empty QList.

I will make QStandardItem's using the constructor

QStandardItem::QStandardItem(const QString & text)

where I get my QString text by parsing a QFile into QStrings.

Everything looking good?

Or maybe I should skip creating QLists and go directly from generating QStandardItem's to passing them into the QStandardItemModel using void QStandardItemModel::setItem(int row, int column, QStandardItem * item)

Edit: I ended up skipping creating QLists with the following process: QFile file -> QString line -> QStringList peices -> QStandardItem -> QStandardItemModel -> QTableView

Thanks to all who contributed


Solution

  • Your approach is correct. You can use QStandardItemModel for your data.

    QStandardItemModel *model = new QStandardItemModel(2,3,this);
    model->setHorizontalHeaderItem(0, new QStandardItem(QString("Column1 Header")));
    model->setHorizontalHeaderItem(1, new QStandardItem(QString("Column2 Header")));
    model->setHorizontalHeaderItem(2, new QStandardItem(QString("Column3 Header")));
    
    ui->tableView->setModel(model);
    

    Than you can add values:

    QStandardItem *firstRow = new QStandardItem(QString("ColumnValue"));
    model->setItem(0,0,firstRow);