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

如您所见,我已经覆盖了 dataroleNames。 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 中实现的模型,其中我概括了逻辑。