Список QSqlTableModel to qml, проходящий несколько раз - PullRequest
2 голосов
/ 21 января 2020

Я новичок и пытаюсь изучить qt и qml, но я не могу найти способ решить эту проблему.

У меня есть QSqlTableModel только с 4 строками тестовых данных, но я хотел бы преобразовать различные значения из 1 столбца (из которых есть только 1 значение) в список для qml ListModel.

У меня есть Q_PROPERTY(QStringList distinctSemesters READ getSemesterList NOTIFY semesterChanged) в моем файле SqlDataModel.h, с этим в моем sqldatamodel. cpp

QStringList  SqlDataModel::getSemesterList() const
{
    QStringList  mySemesters;
    QSqlQuery query;
    query.exec("SELECT DISTINCT Semester FROM results");
    while (query.next()) {
        QString currentSemester = query.value(0).toString();
        mySemesters << currentSemester;
    }
    return mySemesters;
}

, который возвращает QStringList длины 1. Я пытаюсь прочитать это в мой qml с

ListView {
    model: SqlDataModel {
                    id: myModel
                }
    delegate: ItemDelegate {
                width: parent.width
                text: myModel.distinctSemesters
            }
}

, который работает при получении строки из функции getSemesterList (). Но String повторяется в списке 4 раза (размер моей табличной модели). Я проверил это и добавил больше строк в тестовую таблицу, которая продолжает повторять одну и ту же строку несколько раз в моем просмотре списка.

Исходя из моего ограниченного понимания, я предполагаю, что это всегда будет так, потому что просмотр списка берет свой размер из модели - это размер таблицы qsl. Я понятия не имею, как go об этом, может кто-нибудь еще указать мне правильное направление?

В настоящее время я думаю о создании новой sqlmodel для переноса в qml (но мне нужно читать + писать, так что я считаю, что sqltablemodel подходит для этого), или я должен попытаться исправить сторону qml с помощью javascript , Я посмотрел на это в javascript, но когда я попытался

property ListModel distinctSemesters;
Component.onCompleted: {
              console.log(distinctSemesters)

, я продолжал получать сообщения об ошибках, которые не определены.

Любая помощь очень ценится, спасибо.

ниже (я надеюсь) приведен воспроизводимый пример. Я использовал некоторые онлайн-ресурсы для руководства. main. cpp:

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

    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QApplication app(argc, argv);

    qmlRegisterType<SqlDataModel>("GradesSqlDataModel", 1, 0, "SqlDataModel");


    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.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();
}

SqlDataModel.h

class SqlDataModel : public QSqlTableModel
{
    Q_OBJECT
    Q_PROPERTY(QString semester READ getsemester WRITE setSemester NOTIFY semesterChanged)
    Q_PROPERTY(QStringList distinctSemesters READ getSemesterList NOTIFY semesterChanged)

public:
    SqlDataModel(QObject *parent = 0);

    QStringList getSemesterList() const;
    QString getsemester() const;

    QVariant data(const QModelIndex &index, int role) const override;
    QHash<int, QByteArray> roleNames() const override;

signals:
    void semesterChanged();
};

SqlDataModel. cpp

SqlDataModel::SqlDataModel(QObject *parent) :
    QSqlTableModel(parent)
{
    createTable();
    setTable("Results");
    setEditStrategy(QSqlTableModel::OnManualSubmit);
    select();

}

QStringList  SqlDataModel::getSemesterList() const
{
    QStringList  mySemesters;
    QSqlQuery query;
    query.exec("SELECT DISTINCT Semester FROM results");
    while (query.next()) {
        QString currentSemester = query.value(0).toString();
        mySemesters << currentSemester;
        qDebug() << currentSemester;
    }
    qDebug() << "length :" <<mySemesters.length();
    return mySemesters;
}

QHash<int, QByteArray> SqlDataModel::roleNames() const
{
    QHash<int, QByteArray> dataNames;
    dataNames[Qt::UserRole] = "ID";
    dataNames[Qt::UserRole + 1] = "Semester";
    dataNames[Qt::UserRole + 2] = "CourseTitle";
    dataNames[Qt::UserRole + 3] = "TestWeight";
    dataNames[Qt::UserRole + 4] = "TestName";
    dataNames[Qt::UserRole + 5] = "Result";
    dataNames[Qt::UserRole + 6] = "OutOf";
    qDebug() << "DataNames" << dataNames;
    return dataNames;
}
QVariant SqlDataModel::data(const QModelIndex &index, int role) const
{
    qDebug() << "settingData";
    if (role < Qt::UserRole)
        return QSqlTableModel::data(index, role);

    const QSqlRecord sqlRecord = record(index.row());
    return sqlRecord.value(role - Qt::UserRole);
}

main.qml

ApplicationWindow {
    id: window;
    visible: true;
    width: 640;
    height: 600;
    title: qsTr("TEST")

    Drawer {
        id: drawer
        width: Math.min(window.width, window.height) / 3 * 2
        height: window.height
        interactive: true

        ListView {
                  model: SqlDataModel {
                    id: myModel
                }
                delegate: ItemDelegate {
                         width: parent.width
                         text: myModel.distinctSemesters
               }
       }
}   

и моя таблица результатов sql выглядит следующим образом (только с первичным ключом ID):

query.exec("INSERT INTO results (Semester, CourseTitle, TestWeight, TestName, Result, OutOf) VALUES ('Spring 2020', 'Course 1', '10', 'Exam 1', 50, 100)");
    query.exec("INSERT INTO results (Semester, CourseTitle, TestWeight, TestName, Result, OutOf) VALUES ('Spring 2020', 'Course 1', '33', 'Exam 2', 70, 100)");
    query.exec("INSERT INTO results (Semester, CourseTitle, TestWeight, TestName, Result, OutOf) VALUES ('Spring 2020', 'Course 2', '25', 'Exam 1', 0, 100)");
    query.exec("INSERT INTO results (Semester, CourseTitle, TestWeight, TestName, Result, OutOf) VALUES ('Spring 2020', 'Course 2', '5', 'Quiz 1', 5, 20)");

1 Ответ

2 голосов
/ 22 января 2020

Объяснение:

В вашем случае QSqlTableModel загружает все строки таблицы, так как нет фильтра, поэтому у него будет 4 строки, так что любое представление, которое его использует, также покажет те 4 строки, поэтому ListView показывает 4 строки. Почему в каждой строке отображается одна и та же информация? Ну, потому что в каждом пункте у вас есть делегат, который показывает разные «Семестры», которые всегда являются «Весной 2020».

Решение:

В этом случае это не так необходимо использовать QSqlTableModel, так как достаточно QSqlQueryModel, чтобы разрешить фильтрацию из QML, поэтому для этого вы можете использовать модель мой другой ответ . Так что будет достаточно только поместить его в экспорт в QML и использовать его.

qmlRegisterType<SqlQueryModel>("GradesSqlDataModel", 1, 0, "SqlQueryModel");
import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Controls 2.14
import GradesSqlDataModel 1.0

Window {
    id: window
    visible: true
    width: 640;
    height: 600;

    SqlQueryModel{
        id: sqlquerymodel
        query: "SELECT DISTINCT Semester FROM results"
    }
    Drawer {
        id: drawer
        width: Math.min(window.width, window.height) / 3 * 2
        height: window.height
        interactive: true
        ListView{
            anchors.fill: parent
            model: sqlquerymodel
            delegate: ItemDelegate {
                width: parent.width
                text: model.Semester
            }
        }
    }
    Component.onCompleted: drawer.visible = true
}

enter image description here

Полный пример можно найти здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...