QSqlQueryModel - 覆盖未被调用的函数数据
QSqlQueryModel - override function data not being called
我正在尝试使用从 MySQL 数据库检索到的一些信息填充 QML 中的 TableView。
我可以使用 QSqlQuery 连接到数据库,但是当尝试使用 QSqlQueryModel 时,它不起作用(在最后的图像中获得的结果)。我一直在调试应用程序,但是模型的覆盖函数 data
和覆盖函数 roleNames
从未被调用。
这是我的模型文件的样子:tableModel.h
#ifndef TABLEMODEL_H
#define TABLEMODEL_H
#include <QObject>
#include <QtQml/qqml.h>
#include <QSqlQueryModel>
#include <source/database/mySQL/mySqlQueries.h>
class TableModel : public QSqlQueryModel {
Q_OBJECT
public:
// List all the roles that will be used in the TableView
enum Roles {
CHROM_ROLE = Qt::UserRole + 1,
POS_ROLE,
ID_ROLE,
REF_ROLE,
ALT_ROLE,
QUAL_ROLE
};
explicit TableModel(QObject *parent = 0);
// Override the method that will return the data
QVariant data( const QModelIndex & index, int role = Qt::DisplayRole ) const override;
protected:
/* hashed table of roles for speakers.
* The method used in the wilds of the base class QAbstractItemModel,
* from which inherits the class QSqlQueryModel
* */
QHash<int, QByteArray> roleNames() const override;
};
#endif // TABLEMODEL_H
这里,执行文件:tableModel.cpp
#include "tableModel.h"
TableModel::TableModel(QObject *parent) : QSqlQueryModel(parent) {
}
// The method for obtaining data from the model
QVariant TableModel::data( const QModelIndex & index, int role) const {
switch (role) {
case CHROM_ROLE:
return QString("%1, %2").arg(index.column()).arg(index.row());
case POS_ROLE:
return QString("%1, %2").arg(index.column()).arg(index.row());
case ID_ROLE:
return QString("%1, %2").arg(index.column()).arg(index.row());
case REF_ROLE:
return QString("%1, %2").arg(index.column()).arg(index.row());
case ALT_ROLE:
return QString("%1, %2").arg(index.column()).arg(index.row());
case QUAL_ROLE:
return QString("%1, %2").arg(index.column()).arg(index.row());
default:
break;
}
return QVariant();
}
QHash<int, QByteArray> TableModel::roleNames() const {
QHash<int, QByteArray> roles;
roles[CHROM_ROLE] = "CHROM_ROLE";
roles[POS_ROLE] = "POS_ROLE";
roles[ID_ROLE] = "ID_ROLE";
roles[REF_ROLE] = "REF_ROLE";
roles[ALT_ROLE] = "ALT_ROLE";
roles[QUAL_ROLE] = "QUAL_ROLE";
return roles;
}
如您所见,我已经覆盖了 data
和 roleNames
。 None 这些函数在执行时被调用。 (现在,数据应该 return 行号和列号,而不是真实数据)。
包含TableView对象的qml文件对应部分如下:
import QtQuick.Controls 2.4
import QtQuick.Controls 1.4 as Controls
import QtQuick.Window 2.11
import Qt.labs.qmlmodels 1.0
Window {
id: root
visible: true
width: 640
height: 480
title: qsTr("Title")
Controls.TableView {
id: tableview
width: root.width * 0.8
height: root.height * 0.8
anchors.centerIn: parent
clip: true
Controls.TableViewColumn {
role: "CHROM_ROLE" // These roles are roles names coincide with a C ++ model
title: "#Chrom"
}
Controls.TableViewColumn {
role: "POS_ROLE" // These roles are roles names coincide with a C ++ model
title: "Pos."
}
Controls.TableViewColumn {
role: "ID_ROLE" // These roles are roles names coincide with a C ++ model
title: "ID"
}
Controls.TableViewColumn {
role: "REF_ROLE" // These roles are roles names coincide with a C ++ model
title: "Ref."
}
Controls.TableViewColumn {
role: "ALT_ROLE" // These roles are roles names coincide with a C ++ model
title: "Alt."
}
Controls.TableViewColumn {
role: "QUAL_ROLE" // These roles are roles names coincide with a C ++ model
title: "Qual."
}
// We set the model in the TableView
model: TableModel
}
}
如您所见,每个 TableViewColumns 的角色与 cpp 文件中的角色相对应。
pro 文件包含以下行(此外,SQL 查询正在运行):
QT += sql
在 main.cpp 文件中,我正在像这样实例化所有内容。:
QGuiApplication app(argc, argv);
qmlRegisterType<TableModel>("TableModel", 1, 0, "TableModel");
TableModel tableModel;
MySqlConnector db;
db.connectToDB("localhost", "dbname", "user", "Password");
db.open();
// I've tested that the query is working using just QSqlQuery and retrieves info from database
tableModel.setQuery(MySQLQueries::queryBodyOfVCF.arg(1), db.db);
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("TableModel", &tableModel);
const QUrl url(QStringLiteral("qrc:/views/MasterView.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
当我执行它时,这就是我得到的:
预期的结果应该是这样的(在真实数据库中只有一行,并且如评论中所述,tableModel.rowCount()
returns 1 符合预期)。这是应显示的真实数据示例:
chrom pos ref alt qual id
ctg1 9 A C, G 100 rs001
ctg3 12 C T 100 rs002
我的实现有问题吗?我认为我可能误解了某些概念,或者 .h 文件或 .cpp 文件中缺少某些内容。
问题是因为你使用的是item的名称:TableModel
,解决方法是更改context的名称-属性:
engine.rootContext()->setContextProperty("tableModel", &tableModel);
model: tableModel
另一方面,我建议使用 another post 中实现的模型,其中我概括了逻辑。
我正在尝试使用从 MySQL 数据库检索到的一些信息填充 QML 中的 TableView。
我可以使用 QSqlQuery 连接到数据库,但是当尝试使用 QSqlQueryModel 时,它不起作用(在最后的图像中获得的结果)。我一直在调试应用程序,但是模型的覆盖函数 data
和覆盖函数 roleNames
从未被调用。
这是我的模型文件的样子:tableModel.h
#ifndef TABLEMODEL_H
#define TABLEMODEL_H
#include <QObject>
#include <QtQml/qqml.h>
#include <QSqlQueryModel>
#include <source/database/mySQL/mySqlQueries.h>
class TableModel : public QSqlQueryModel {
Q_OBJECT
public:
// List all the roles that will be used in the TableView
enum Roles {
CHROM_ROLE = Qt::UserRole + 1,
POS_ROLE,
ID_ROLE,
REF_ROLE,
ALT_ROLE,
QUAL_ROLE
};
explicit TableModel(QObject *parent = 0);
// Override the method that will return the data
QVariant data( const QModelIndex & index, int role = Qt::DisplayRole ) const override;
protected:
/* hashed table of roles for speakers.
* The method used in the wilds of the base class QAbstractItemModel,
* from which inherits the class QSqlQueryModel
* */
QHash<int, QByteArray> roleNames() const override;
};
#endif // TABLEMODEL_H
这里,执行文件:tableModel.cpp
#include "tableModel.h"
TableModel::TableModel(QObject *parent) : QSqlQueryModel(parent) {
}
// The method for obtaining data from the model
QVariant TableModel::data( const QModelIndex & index, int role) const {
switch (role) {
case CHROM_ROLE:
return QString("%1, %2").arg(index.column()).arg(index.row());
case POS_ROLE:
return QString("%1, %2").arg(index.column()).arg(index.row());
case ID_ROLE:
return QString("%1, %2").arg(index.column()).arg(index.row());
case REF_ROLE:
return QString("%1, %2").arg(index.column()).arg(index.row());
case ALT_ROLE:
return QString("%1, %2").arg(index.column()).arg(index.row());
case QUAL_ROLE:
return QString("%1, %2").arg(index.column()).arg(index.row());
default:
break;
}
return QVariant();
}
QHash<int, QByteArray> TableModel::roleNames() const {
QHash<int, QByteArray> roles;
roles[CHROM_ROLE] = "CHROM_ROLE";
roles[POS_ROLE] = "POS_ROLE";
roles[ID_ROLE] = "ID_ROLE";
roles[REF_ROLE] = "REF_ROLE";
roles[ALT_ROLE] = "ALT_ROLE";
roles[QUAL_ROLE] = "QUAL_ROLE";
return roles;
}
如您所见,我已经覆盖了 data
和 roleNames
。 None 这些函数在执行时被调用。 (现在,数据应该 return 行号和列号,而不是真实数据)。
包含TableView对象的qml文件对应部分如下:
import QtQuick.Controls 2.4
import QtQuick.Controls 1.4 as Controls
import QtQuick.Window 2.11
import Qt.labs.qmlmodels 1.0
Window {
id: root
visible: true
width: 640
height: 480
title: qsTr("Title")
Controls.TableView {
id: tableview
width: root.width * 0.8
height: root.height * 0.8
anchors.centerIn: parent
clip: true
Controls.TableViewColumn {
role: "CHROM_ROLE" // These roles are roles names coincide with a C ++ model
title: "#Chrom"
}
Controls.TableViewColumn {
role: "POS_ROLE" // These roles are roles names coincide with a C ++ model
title: "Pos."
}
Controls.TableViewColumn {
role: "ID_ROLE" // These roles are roles names coincide with a C ++ model
title: "ID"
}
Controls.TableViewColumn {
role: "REF_ROLE" // These roles are roles names coincide with a C ++ model
title: "Ref."
}
Controls.TableViewColumn {
role: "ALT_ROLE" // These roles are roles names coincide with a C ++ model
title: "Alt."
}
Controls.TableViewColumn {
role: "QUAL_ROLE" // These roles are roles names coincide with a C ++ model
title: "Qual."
}
// We set the model in the TableView
model: TableModel
}
}
如您所见,每个 TableViewColumns 的角色与 cpp 文件中的角色相对应。
pro 文件包含以下行(此外,SQL 查询正在运行):
QT += sql
在 main.cpp 文件中,我正在像这样实例化所有内容。:
QGuiApplication app(argc, argv);
qmlRegisterType<TableModel>("TableModel", 1, 0, "TableModel");
TableModel tableModel;
MySqlConnector db;
db.connectToDB("localhost", "dbname", "user", "Password");
db.open();
// I've tested that the query is working using just QSqlQuery and retrieves info from database
tableModel.setQuery(MySQLQueries::queryBodyOfVCF.arg(1), db.db);
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("TableModel", &tableModel);
const QUrl url(QStringLiteral("qrc:/views/MasterView.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
当我执行它时,这就是我得到的:
预期的结果应该是这样的(在真实数据库中只有一行,并且如评论中所述,tableModel.rowCount()
returns 1 符合预期)。这是应显示的真实数据示例:
chrom pos ref alt qual id
ctg1 9 A C, G 100 rs001
ctg3 12 C T 100 rs002
我的实现有问题吗?我认为我可能误解了某些概念,或者 .h 文件或 .cpp 文件中缺少某些内容。
问题是因为你使用的是item的名称:TableModel
,解决方法是更改context的名称-属性:
engine.rootContext()->setContextProperty("tableModel", &tableModel);
model: tableModel
另一方面,我建议使用 another post 中实现的模型,其中我概括了逻辑。