在C++中,Qt常用的的Sql数据库有QSqlTableModel,QSqlQueryModel等等,用于数据库处理很方便,那么如果需要在QML中显示SQL数据库数据,要怎么处理呢?C++中的SQL处理的Model模块不支持直接给QML使用,需要将其继承后添加数据绑定的部分功能后,再交由QML进行展示。
头文件:qmlsqlquerymodel.h
#ifndef QMLSQLQUERYMODEL_H
#define QMLSQLQUERYMODEL_H
#include <QSqlQueryModel>
#include <QSqlRecord>
#include <QObject>
#include <QDebug>
#include <QQmlPropertyMap>
class QmlSqlQueryModel : public QSqlQueryModel
{
Q_OBJECT
public:
QmlSqlQueryModel(QObject *parent = nullptr);
QVariant data(const QModelIndex &index, int role) const;
Q_INVOKABLE QVariantList getHeaderList();//获得表头列名
Q_INVOKABLE bool isSqlModel();//标识符,用于自定义的TableView控件检测
protected:
QHash<int,QByteArray>roleNames() const;//将列名称暴露给QML
};
#endif
1、设置roleNames(),将各数据列的名称传递给QML,数据展示中的Delegate按照列名称绑定数据
QHash<int, QByteArray> QmlSqlQueryModel::roleNames() const
{
QHash<int, QByteArray> roles;
for (int i = 0; i < this->record().count(); i ++) {
roles.insert(Qt::UserRole + i + 1, record().fieldName(i).toUtf8());
}
return roles;
}
2、将SqlModel中的数据值传递给QML
QVariant QmlSqlQueryModel::data(const QModelIndex &index, int role) const
{
QVariant value;
if (index.isValid()) {
if (role < Qt::UserRole) {
value = QSqlQueryModel::data(index, role);
} else {
int columnIdx = role - Qt::UserRole - 1;
QModelIndex modelIndex = this->index(index.row(), columnIdx);
value = QSqlQueryModel::data(modelIndex, Qt::DisplayRole);
}
}
return value;
}
完成以上两步,在QML中把各列按照列名绑定到对应Delete上即可显示数据,如果觉得自己写数据绑定比较麻烦,且不灵活,当数据库列表结构发生变化时需要修改代码才行,那么可以使用我自己制作的TableView控件,当使用该TableView控件加载model时,控件自动绑定数据列,因此需要添加以下两个功能:
QVariantList QmlSqlQueryModel::getHeaderList()
{
QVariantList list;
for(int i=0;i<this->record().count();i++){
QString key = this->record().fieldName(i);
list.append(key);
}
return list;
}
bool QmlSqlQueryModel::isSqlModel()
{
return true;
}
至此,配合着TableView使用,基本上达到了C++中使用QTableView加载SQL Model的效果,代码文件我上传了,直接下载添加到工程即可使用,QmlSqulQueryModel和TableView控件的下载地址:
TableView控件介绍:QML 自定义TableView控件(在ListView基础上实现类似QTableView功能)
QmlSqlQueryModel下载地址:QmlSqlQueryModelhttps://github.com/zjgo007/QmlDemo/tree/master/QmlSqlQueryModel