gpt4 book ai didi

c++ - 将 QSqlQueryModel 数据转换为 QVector(s)

转载 作者:行者123 更新时间:2023-11-27 23:13:44 25 4
gpt4 key购买 nike

如果我们使用以下 QT 功能从 SQL 数据库获取数据

 QSqlQueryModel *model = new QSqlQueryModel;
model->setQuery("SELECT name, salary FROM employee");

它在随附的 Material 中说明我们可以使用以下任一命令访问单个元素

 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 列) 进入矩阵库,例如 Armadillo 或 Eigen。

我正在处理的数据可能很大,因此效率很重要,因此使用一组简单的 for 循环似乎是一个非常糟糕的主意。

非常感谢任何帮助。

最佳答案

我建议看一下 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 函数中,您提供一个映射逻辑列中的索引到完整数据集中的索引,以及 rows() 和 columns() 的正确值.. rest 会自动为您完成,只要 ProxyModel 只是一个模型,您就可以在任何 UI 控件或任何你喜欢的其他方式。我经常使用代理模型,一旦你习惯了它就会非常方便。

我会尝试举一些例子,希望它能让你明白...Qt 中的模型(无论它有什么类型)是一组数据。根据类型的不同,它可以是包含行和列的表格(显然,只有一列的模型是一个列表),也可以是更高级的东西,例如树,您可以在其中拥有更复杂的层次结构,但我们暂时保留它。

因此,QSqlQueryModel 是一个包含行和列的平面表,其中行 - 是结果集中的记录数,列是您通过查询获取的列数。

假设你有类似的东西

第 1 列第 2 列第 3 列

1 2 个 4 3 伏 5 f f

从数学的角度来看,你可以称之为矩阵。

QModelIndex - 是一个表示模型中“位置”的类。为简单起见,您可以将其视为表示对 { 行,列 }

的东西

所以你可以使用方法从模型中获取数据

 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

所以,接近主题......你的任务是提取一个 vector ,所以假设任何矩阵列的一部分......所以你定义一个类:

 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();
}

希望它能解释更多,我的回答是什么意思

关于c++ - 将 QSqlQueryModel 数据转换为 QVector(s),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18128722/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com