1

我想在 qml TableView 中显示 QSqlQueryModel 但我不想为每个新查询创建单独的 QML 文件,因为我无法创建这里给出的无限 qml 文件。对于动态列数,问题也不适用于我(可能是版本差异,因为我使用的是 5.11)。我只想要类似的东西:-

QTableView *view = new QTableView;
view->setModel(model);
view->show();

在 QML 中。

我是qml的新手。到目前为止,我能够按照第一个链接中的指导显示 QSqlQueryModel,但我的用户可以输入任何 SQL 查询。

4

1 回答 1

6

使用来自如何在 QML 中使用 QSqlQueryModel的更通用方法中的 信息,您可以构建一个通用模型,以便从 QML 中轻松使用,您可以创建一个属性来传递查询。

sqlquerymodel.h

#ifndef SQLQUERYMODEL_H
#define SQLQUERYMODEL_H

#include <QSqlQuery>
#include <QSqlQueryModel>
#include <QSqlRecord>

class SqlQueryModel : public QSqlQueryModel
{
    Q_OBJECT
    Q_PROPERTY(QString query READ queryStr WRITE setQueryStr NOTIFY queryStrChanged)
    Q_PROPERTY(QStringList userRoleNames READ userRoleNames CONSTANT)
public:
    using QSqlQueryModel::QSqlQueryModel;
    QHash<int, QByteArray> roleNames() const
    {
       QHash<int, QByteArray> roles;
       for (int i = 0; i < record().count(); i ++) {
           roles.insert(Qt::UserRole + i + 1, record().fieldName(i).toUtf8());
       }
       return roles;
   }
    QVariant data(const QModelIndex &index, int role) const
    {
        QVariant value;
        if (index.isValid()) {
            if (role < Qt::UserRole) {
                value = QSqlQueryModel::data(index, role);
            } else {
                int columnIdx = role - Qt::UserRole - 1;
                QModelIndex modelIndex = this->index(index.row(), columnIdx);
                value = QSqlQueryModel::data(modelIndex, Qt::DisplayRole);
            }
        }
        return value;
    }
    QString queryStr() const{
        return query().lastQuery();
    }
    void setQueryStr(const QString &query){
        if(queryStr() == query)
            return;
        setQuery(query);
        emit queryStrChanged();
    }
    QStringList userRoleNames() const {
        QStringList names;
        for (int i = 0; i < record().count(); i ++) {
            names << record().fieldName(i).toUtf8();
        }
        return names;
    }
signals:
    void queryStrChanged();
};
#endif // SQLQUERYMODEL_H

主文件

#include "sqlquerymodel.h"

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QDebug>
#include <QSqlError>

static bool createConnection()
{

    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(":memory:");
    if (!db.open()) {
        qDebug()<<"Cannot open database\n"
                  "Unable to establish a database connection.\n"
                  "This example needs SQLite support. Please read "
                  "the Qt SQL driver documentation for information how "
                  "to build it.\n\n"
                  "Click Cancel to exit.";
        return false;
    }

    QSqlQuery query;
    if(!query.exec("CREATE TABLE COMPANY("
                   "ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
                   "NAME           TEXT    NOT NULL,"
                   "AGE            INT     NOT NULL,"
                   "SALARY         REAL"
                   ")")){
        qDebug()<<query.lastError().text();
    }
    for(int i=0; i < 10; i++){
        query.prepare("insert into COMPANY(NAME, AGE, SALARY) values(:name, :age, :salary)");
        query.bindValue(":name", QString("name-%1").arg(i));
        query.bindValue(":age",  (i+1)*1000);
        query.bindValue(":salary", (11-i)*11.5);
        if(!query.exec()){
            qDebug()<<query.lastError().text();
        }
    }
    return true;
}


int main(int argc, char *argv[])
{
    qmlRegisterType<SqlQueryModel>("Foo", 1, 0, "SqlQueryModel");
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);
    if(!createConnection())
        return -1;

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4

import Foo 1.0

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("SqlQueryModel")
    SqlQueryModel{
        id: sqlmodel
        query: "select * from COMPANY"
    }
    Component{
        id: columnComponent
        TableViewColumn{width: 100 }
    }
    TableView {
        id: view
        anchors.fill: parent
        resources:{
            var roleList = sqlmodel.userRoleNames
            var temp = []
            for(var i in roleList){
                var role  = roleList[i]
                temp.push(columnComponent.createObject(view, { "role": role, "title": role}))
            }
            return temp
        }
        model: sqlmodel
    }
}

在此处输入图像描述

于 2018-09-23T19:19:39.230 回答