How to assign SQL query output model from Qt to QM

2019-04-14 06:23发布

From C++ (Qt):

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    /*
     * I have omitted the code about connection with the database and all for ease of   
     * viewing the code.
     */


    // My own function for filling in the data in the `QSqlQueryModel`
    QSqlQueryModel* model = new QSqlQueryModel;
    QString binid = "B1";
    QString query = "SELECT t1.BinId, t1.PartitionId, t2.UnitId, t2.ItemCount FROM Bin_Partitions AS t1 "
                    "INNER JOIN Partition_Units AS t2 ON t1.PartitionId = t2.PartitionId "
                    "WHERE t1.BinId ='" + binid + "'";
    model->setQuery(query);

    /*
     * I can see that the query runs successfully because the following
     * QTableView DOES get populated properly. 
     */
    // Use QTableView to visualize
    QTableView *view = new QTableView;
    view->setModel(model);
    view->show();

    QQmlApplicationEngine engine;
    // Passing the same model to QML for displaying in the TableView.
    engine.rootContext()->setContextProperty ("SQQL", model);
    engine.load(QUrl(QStringLiteral("/home/.../main.qml")));

    QObject               *topLevel  = engine.rootObjects ().value (0);
    QQuickWindow          *window    = qobject_cast <QQuickWindow *> (topLevel);

    return app.exec();
}

From QML:

import QtQuick 2.2
import QtQuick.Window 2.1
import QtQuick.Controls 1.2

Window
{
    visible: true
    width: 360
    height: 360
    color: "blue"

    TableView
    {
        TableViewColumn{ role: "col1" ; title: "BinId" ; visible: true}
        TableViewColumn{ role: "col2" ; title: "PartitionId" }
        TableViewColumn{ role: "col3" ; title: "UnitId" }
        TableViewColumn{ role: "col4" ; title: "ItemCount" }

        model: SQQL
    }
}

The TableView of QML shows up EMPTY!

I need help.

1条回答
叼着烟拽天下
2楼-- · 2019-04-14 06:54

You have to subclass QSqlQueryModel and reimplement roleNames and data methods

MySqlModel.h

class MySqlModel: public QSqlQueryModel
{
    Q_OBJECT
public:
    MySqlModel(QObject *parent = 0) : QSqlQueryModel(parent) {}

    enum Roles {
        BinId = Qt::UserRole + 1,
        PartitionId,
        UnitId,
        ItemCount
    };
    QHash<int, QByteArray> roleNames() const {
        QHash<int, QByteArray> roles;
        roles[BinId] = "binIdRole";
        roles[PartitionId] = "partitionIdRole";
        roles[UnitId] = "unitIdRole";
        roles[ItemCount] = "itemCountRole";
        return roles;
    }
    QVariant data(const QModelIndex &index, int role) const {
        if (!index.isValid())
            return QVariant();

        QString fieldName;
        switch (role) {
            case BinId: fieldName = QStringLiteral("t1.BinId"); break;
            case PartitionId: fieldName = QStringLiteral("t1.PartitionId"); break;
            case UnitId: fieldName = QStringLiteral("t2.UnitId"); break;
            case ItemCount: fieldName = QStringLiteral("t2.ItemCount"); break;
        }
        if (!this->record().isGenerated(fieldName))
            return QVariant();
        else {
            QModelIndex item = indexInQuery(index);
            if ( !this->query().seek(item.row()) )
                return QVariant();
            return this->query().value(fieldName);
        }
        return QVariant();
    }
};

main.qml

Window  {
    visible: true
    width: 640
    height: 480
    TableView {
        anchors.fill: parent
        model: SQQL
        TableViewColumn{ role: "binIdRole" ; title: "BinId" ; visible: true}
        TableViewColumn{ role: "partitionIdRole" ; title: "PartitionId" }
        TableViewColumn{ role: "unitIdRole" ; title: "UnitId" }
        TableViewColumn{ role: "itemCountRole" ; title: "ItemCount" }
    }
}
查看更多
登录 后发表回答