QSqlQueryModel - 覆盖未调用的函数数据
Posted
技术标签:
【中文标题】QSqlQueryModel - 覆盖未调用的函数数据【英文标题】:QSqlQueryModel - override function data not being called 【发布时间】: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
没有被执行。
【参考方案1】:
问题是因为你使用了item的名称:TableModel
,解决方法是更改context-property的名称:
engine.rootContext()->setContextProperty("tableModel", &tableModel);
model: tableModel
另一方面,我建议使用在another post 中实现的模型,我在其中概括了逻辑。
【讨论】:
像魅力一样工作!非常感谢。那么问题是它使用的是类型而不是对象。当然,我会检查您链接的帖子中实现的模型并更改我的实现。事实是,找到这方面的例子有点困难,所以谢谢你的链接。以上是关于QSqlQueryModel - 覆盖未调用的函数数据的主要内容,如果未能解决你的问题,请参考以下文章
使用情节提要时未调用 UITableViewController 覆盖初始化函数