如果我们使用以下QT功能从SQL数据库获取数据
QSqlQueryModel *model = new QSqlQueryModel;
model->setQuery("SELECT name, salary FROM employee");
它在随附的材料中说明我们可以使用以下任一命令访问单个元素
int salary = model.record(4).value("salary").toInt();
或
int salary = model.data(model.index(4, 2)).toInt();
我们可以使用
将这些数据插入到QTableView中 QTableView *view = new QTableView;
view->setModel(model);
而且这个数据也可以。但是,我可以在任何地方看到如何提取整列数据或列/行范围(或者如QSqlQueryModel索引和角色的术语)。
最终我想要做的是有效地将部分数据提取到QVectors,例如数据的第3列。或者可能使用某种getDataFunc(QVector行,QVector列)进入犰狳或Eigen等矩阵库。
我正在工作的数据可能很大,因此效率很高,因此使用一组天真的for循环似乎是一个非常糟糕的主意。
任何帮助都非常感激。
答案 0 :(得分:4)
我建议看看QAbstractProxyModel。特别是考虑到你有一个巨大的数据集,所以在不同的地方之间复制它们对我来说并不好看。
所以在代码语言中我想我会创建类似的东西:
class RowsInColumnProxyModel: public QAbstractProxyModel {
....
void setTargetColumn( int column );
void setRowsRange(int minRow, int maxRow);
int rowCount(..);
int columnCount(..);
... whatever else on your taste from QAbstractItemModel ...
virtual QModelIndex mapFromSource(const QModelIndex & sourceIndex) const;
virtual QModelIndex mapToSource(const QModelIndex & proxyIndex) const;
}
您可能希望查看Qt文档,因为有大量示例可用。想法是在mapFrom和mapTo函数内部提供一个映射的逻辑 将列中的索引转换为完整数据集中的索引,以及行()和列()的正确值。休息是自动完成的,只要ProxyModel只是一个模型,您就可以在任何UI控件或任何UI控件中使用它其他你喜欢的方式。我经常使用代理模型,一旦你习惯它就很方便。
我会尝试做一些例子,希望它会为你清楚...... Qt中的模型(无论它有什么类型)都是一组数据。根据类型,它可以是一个包含行和列的表(显然有一列是一个列表的模型),或者像树一样更高级的东西,你可以有更复杂的层次结构,但现在让我们离开它。
因此,QSqlQueryModel是一个包含行和列的平面表,其中rows - 是结果集中的多个记录,列是您使用查询获取的列数。
假设您有类似
的内容Col1 Col2 Col3
1 2 a 4 3 v 5 f f
从数学预期的角度来看,你可以把它称为矩阵。
QModelIndex - 是一个表示模型中“位置”的类。为简单起见,您可以将其视为代表对{row,column}
的内容因此您可以使用方法
从模型中获取数据 QVariant data( QModelIndex, DisplayRole)
此方法将返回位于QModelIndex描述的位置的单元格的内容。要转换物理行和列,您应该使用方法
QModelIndex index(int row, int column, QModelIndex & parent = QModelIndex());
你现在可以忽略最后一个参数(它只在树模型上使用),所以要从平面模型中获取任何单元格(QSqlRecordModel是),你可以使用如下代码:
QVariant value = model.data( model.index( row, column) );
int intValue = value.toInt();
.. or in case you expect a string
QString strValue = value.toString()
.. etc
所以,接近主题...你的任务是提取一个向量,所以让我们说任何矩阵列的一部分...所以你定义一个类,如:
class Vector: public QAbstractProxyModel {
protected:
// make them =0 in constructor
int m_column;
int m_minRow;
int m_maxRow;
...
void setTargetColumn( int column ) {
// emitting signals important to let rest of the world now about changes
emit beginResetModel();
m_column = column;
emit endResetModel();
}
void setRowsRange( int minRow, int maxRow ) {
// emitting signals important to let rest of the world now about changes
emit beginResetModel();
m_minRow = minRow;
m_maxRow = maxRow;
emit endResetModel();
}
virtual int columnCount(const QModelIndex & parent = QModelIndex()) {
return 1; // since it's vector
}
virtual int rowCount(const QModelIndex & parent = QModelIndex()) {
return m_maxRow - m_minRow;
}
.. now most exciting part..
virtual QModelIndex mapFromSource(const QModelIndex & sourceIndex) const {
int sourceRow = sourceIndex.row();
int sourceColumn = sourceIndex.column();
int targetColumn = 0; // only one in vector
int targetRow = sourceRow - m_minRow;
return modelIndex( targetRow, targetColumn );
}
virtual QModelIndex mapToSource(const QModelIndex & proxyIndex) const {
// same as above but a bit shorter
return index( proxyIndex.row()+m_minRow, m_column );
}
}
好吧,我们有一个让我们用它的课程
QSqlRecordModel * sourceModel = ... (so, it's something)
Vector * myVector = new Vector();
myVector->setSourceModel( sourceModel );
myVector->setTargetColumn(3);
myVector->setRowsRange(5, 10);
...
for (int i=0;i<myVector->rowCount();i++) {
int vectorItem = myVector->data( myVector->index(i,0) ).toInt();
}
希望它能解释一下,我的回答是什么意思