QSqlQueryModel – override function data not being called

  c++, model, qml, qt

I am trying to populate a TableView in QML with some information retrieved from a MySQL database.

I am able to connect to the database using QSqlQuery, but when trying to use QSqlQueryModel, it is not working (results obtained in the image at the end). I’ve been debugging the application, but the overrided function data and the overrided function roleNames of the model are never called.

This is how my model file looks like: 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

Here, the implementation of the file: 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;
}

As you can see, I’ve overrided data and roleNames. None of those functions are called when executing it. (Right now, data should return the row and column numbers, not the real data).

The corresponding part of the qml file containing the TableView object is the following:

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
        }


}

As you can see, the roles for each of the TableViewColumns, corresponds with the roles in the cpp file.

The pro file contains the following line (besides, SQL queries are working):

QT += sql

In the main.cpp file, I am instantiating everything like this.:

    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();

When I execute it, this is what I am getting:

Results of executing the previous code.

The expected results should be something like this:

  chrom   pos   ref      alt   qual      id
   ctg1     9     A     C, G    100   rs001
   ctg3    12     C        T    100   rs002

Is there something wrong with my implementation? I think that I may be me misunderstanding some concept, or something missing in the .h file or the .cpp file.

Source: Windows Questions C++

LEAVE A COMMENT