使用 QTableView 在 Qt C++ 中读取和查看制表符分隔的 txt 文件
Read and view tab-delimited txt files in Qt C++ using QTableView
我需要一些一般性建议来指出解决此问题的正确方向:我有一个包含 table 数据的 .txt 文件,如下所示:
Time Pin
11:00 EIO4
12:55 EIO6
16:40 EIO4
20:10 EIO3
etc......
我需要能够解析此 .txt 文件。然后我需要在 Qt 中显示这个 table(可能在 QTableView
中)。
我研究过使用 QTableView,看来我使用 QTableView::setModel(QAbstractItemModel* model)
将 QAbstractItemModel*
传递给 QTableView
,之后我的 QTableView 将显示 QAbstractItemModel 中的任何数据(对吧?)。
如果最后一段是合乎逻辑的,那么我的下一个问题是如何使用我的 .txt 文件构建 QAbstractItemModel
?我在文档中没有看到执行此操作的任何功能? (注意:有人建议创建一个 QStandardItemModel)
(注意,此段不再相关)QModelIndex createIndex(int row, int column, void* ptr)
似乎与此有关,也许吧?也许这会创建一个可以使用 QAbstractItemModel::insertRow(QModelIndex)
传递给 QAbstractItemModel
的 QModelIndex
?但是我仍然不知道如何使这些 QModelIndex
对象与我的 .txt 数据有任何关系。
QStandardItemModel
文档说
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()
.
这些 "add rows" 的函数将 QList<QStandardItem*>
作为参数,所以我需要创建 QList,每个 QList 都包含包含每个单元格数据的指针 QStandardItems?
所以我会用
void QStandardItemModel::insertRow(int row, const QList<QStandardItem *> & items)
http://doc.qt.io/qt-5/qstandarditemmodel.html#insertRow
连同通过重复调用“<<
”生成的参数 QList<QStandardItem*>
传递 QStandardItem*
指向空 QList
的指针。
我将使用构造函数
制作QStandardItem
QStandardItem::QStandardItem(const QString & text)
我通过将 QFile 解析为 QString 来获得我的 QString text
。
一切都很好吗?
或者我应该跳过创建 QList,直接从生成 QStandardItem
到使用 void QStandardItemModel::setItem(int row, int column, QStandardItem * item)
将它们传递到 QStandardItemModel
编辑:
我最终跳过了使用以下过程创建 QLists 的过程:
QFile 文件 -> QString 行 -> QStringList 文件 -> QStandardItem -> QStandardItemModel -> QTableView
感谢所有贡献者
你的做法是正确的。您可以使用 QStandardItemModel 作为数据。
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);
你可以添加的值:
QStandardItem *firstRow = new QStandardItem(QString("ColumnValue"));
model->setItem(0,0,firstRow);
对于最初的问题,即如何创建自定义模型:这相当容易,因为 table 模型有一个方便的基础 class,QAbstractTableModel
实现了大部分通用模型接口的毛茸茸的方法。
自定义 table 模型的第一步是确定单行的数据类型,例如
struct Data
{
QTime time;
QString pin;
};
自定义模型随后可以对该类型的列表或向量进行操作。
class MyModel : public QAbstractItemModel
{
private:
QVector<Data> m_data;
};
然后可以通过返回 list/vector 的 size/count 来简单地实现 rowCount()
方法,columnCount()
是固定的(本例中为 2)并且 data()
可以简单地访问 n-th 条目并打开请求的列:
QVariant MyModel::data(const QModelIndex &index, int role) const
{
const Data &rowData = m_data[index.row()];
switch (index.row()) {
case 0: {
if (role == Qt::DisplayRole) return rowData.time.toString("hh:mm"); // or whatever format you'd like
else if (role == Qt::EditRole) return rowData.time; // return as QTime
break;
}
case 1: if (role == Qt::DisplayRole || role == Qt::EditRole) return rowData.pin;
break;
default: break;
}
return QVariant();
}
可选择实施 headerData()
以获取 "Time" 和 "PIN" 作为列 headers
我需要一些一般性建议来指出解决此问题的正确方向:我有一个包含 table 数据的 .txt 文件,如下所示:
Time Pin
11:00 EIO4
12:55 EIO6
16:40 EIO4
20:10 EIO3
etc......
我需要能够解析此 .txt 文件。然后我需要在 Qt 中显示这个 table(可能在 QTableView
中)。
我研究过使用 QTableView,看来我使用 QTableView::setModel(QAbstractItemModel* model)
将 QAbstractItemModel*
传递给 QTableView
,之后我的 QTableView 将显示 QAbstractItemModel 中的任何数据(对吧?)。
如果最后一段是合乎逻辑的,那么我的下一个问题是如何使用我的 .txt 文件构建 QAbstractItemModel
?我在文档中没有看到执行此操作的任何功能? (注意:有人建议创建一个 QStandardItemModel)
(注意,此段不再相关)QModelIndex createIndex(int row, int column, void* ptr)
似乎与此有关,也许吧?也许这会创建一个可以使用 QAbstractItemModel::insertRow(QModelIndex)
传递给 QAbstractItemModel
的 QModelIndex
?但是我仍然不知道如何使这些 QModelIndex
对象与我的 .txt 数据有任何关系。
QStandardItemModel
文档说
When you want a list or tree, you typically create an empty
QStandardItemModel
and useappendRow()
to add items to the model, anditem()
to access an item. If your model represents a table, you typically pass the dimensions of the table to theQStandardItemModel
constructor and usesetItem()
to position items into the table. You can also usesetRowCount()
andsetColumnCount()
to alter the dimensions of the model. To insert items, useinsertRow()
orinsertColumn()
, and to remove items, useremoveRow()
orremoveColumn()
.
这些 "add rows" 的函数将 QList<QStandardItem*>
作为参数,所以我需要创建 QList,每个 QList 都包含包含每个单元格数据的指针 QStandardItems?
所以我会用
void QStandardItemModel::insertRow(int row, const QList<QStandardItem *> & items)
http://doc.qt.io/qt-5/qstandarditemmodel.html#insertRow
连同通过重复调用“<<
”生成的参数 QList<QStandardItem*>
传递 QStandardItem*
指向空 QList
的指针。
我将使用构造函数
制作QStandardItem
QStandardItem::QStandardItem(const QString & text)
我通过将 QFile 解析为 QString 来获得我的 QString text
。
一切都很好吗?
或者我应该跳过创建 QList,直接从生成 QStandardItem
到使用 void QStandardItemModel::setItem(int row, int column, QStandardItem * item)
QStandardItemModel
编辑: 我最终跳过了使用以下过程创建 QLists 的过程: QFile 文件 -> QString 行 -> QStringList 文件 -> QStandardItem -> QStandardItemModel -> QTableView
感谢所有贡献者
你的做法是正确的。您可以使用 QStandardItemModel 作为数据。
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);
你可以添加的值:
QStandardItem *firstRow = new QStandardItem(QString("ColumnValue"));
model->setItem(0,0,firstRow);
对于最初的问题,即如何创建自定义模型:这相当容易,因为 table 模型有一个方便的基础 class,QAbstractTableModel
实现了大部分通用模型接口的毛茸茸的方法。
自定义 table 模型的第一步是确定单行的数据类型,例如
struct Data
{
QTime time;
QString pin;
};
自定义模型随后可以对该类型的列表或向量进行操作。
class MyModel : public QAbstractItemModel
{
private:
QVector<Data> m_data;
};
然后可以通过返回 list/vector 的 size/count 来简单地实现 rowCount()
方法,columnCount()
是固定的(本例中为 2)并且 data()
可以简单地访问 n-th 条目并打开请求的列:
QVariant MyModel::data(const QModelIndex &index, int role) const
{
const Data &rowData = m_data[index.row()];
switch (index.row()) {
case 0: {
if (role == Qt::DisplayRole) return rowData.time.toString("hh:mm"); // or whatever format you'd like
else if (role == Qt::EditRole) return rowData.time; // return as QTime
break;
}
case 1: if (role == Qt::DisplayRole || role == Qt::EditRole) return rowData.pin;
break;
default: break;
}
return QVariant();
}
可选择实施 headerData()
以获取 "Time" 和 "PIN" 作为列 headers