【发布时间】:2021-03-03 19:44:08
【问题描述】:
我正在尝试使用从 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。执行时不会调用这些函数。 (现在,data 应该返回行号和列号,而不是真实数据)。
包含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();
当我执行它时,这就是我得到的:
预期的结果应该是这样的(在真实的数据库中只有一行,并且如 cmets 中所述,tableModel.rowCount() 按预期返回 1)。这是应显示的真实数据示例:
chrom pos ref alt qual id
ctg1 9 A C, G 100 rs001
ctg3 12 C T 100 rs002
我的实现有问题吗?我认为我可能误解了某些概念,或者 .h 文件或 .cpp 文件中缺少某些内容。
【问题讨论】:
-
删除
qmlRegisterType<TableModel>("TableModel", 1, 0, "TableModel");。同时提供minimal reproducible example。还要在tableModel.setQuery(MySQLQueries::queryBodyOfVCF.arg(1), db.db);之后添加qDebug() << tableModel.rowCount(); -
谢谢。
qDebug() << tableModel.rowCount();返回 1(正如预期的那样,因为 MySQL 工作台也只返回一行)。删除qmlRegisterType<TableModel>("TableModel", 1, 0, "TableModel");并不能解决问题,但我明白你为什么要我删除它。 -
嗯,我已经理解错误了。我认为错误是行数,因为在图像中显示为 1,但在预期的输出中显示为 2。现在我明白错误是因为它出现 TABLEVIEW_QMLTYPE_....
-
我的错,我没有说清楚。我已经编辑了这个问题,所以很明显这是一个输出示例。我在数据库中插入了另一个条目,因此查询现在在 MySQL Workbench 中返回 2 行。
qDebug() << tableModel.rowCount();正在打印 2。但是,GUI 中的输出完全相同,只有一行显示TABLEVIEW_QMLTYPE_46...(),而函数data和roleNames没有被执行。