私は新しく、qtとqmlを学ぼうとしていますが、この問題を解決する方法を見つけることができません。
テストデータが4行しかないQSqlTableModelがありますが、1列(値は1つだけ)の個別の値をqmlListModelのリストに変換したいと思います。
これ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;
}
これは長さ1のQStringListを返します。これをqmlに読み込もうとしています。
ListView {
model: SqlDataModel {
id: myModel
}
delegate: ItemDelegate {
width: parent.width
text: myModel.distinctSemesters
}
}
これは、getSemesterList()関数から文字列を取得する際に機能します。しかし、文字列はリストビューで4回繰り返されます(私のテーブルモデルのサイズ)。これを確認し、テストテーブルに行を追加しました。これにより、リストビューで同じ文字列が何度も繰り返されます。
私の限られた理解から、リストビューはモデルからそのサイズ(qslテーブルのサイズ)を取得しているため、これは常に当てはまると思います。私はこれについてどうやって行くのか分かりません、他の誰かが私を正しい方向に向けることができますか?
私の現在の考えは、qmlに取り込む新しいsqlmodelを作成することです(ただし、読み取りと書き込みが必要なので、sqltablemodelがそれに適していると思います)、またはjavascriptでqml側を修正する必要があります。私はJavaScriptでそれを調べましたが、試したとき
property ListModel distinctSemesters;
Component.onCompleted: {
console.log(distinctSemesters)
私は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)");
説明:
あなたの場合、QSqlTableModelはフィルターがないため、テーブルのすべての行をロードします。したがって、4行になるため、QSqlTableModelを使用するビューでも、これらの4行が表示されるため、ListViewには4行が表示されます。各行に同じ情報が表示されるのはなぜですか?ええと、各アイテムで、代表者が常に「2020年春」である異なる「学期」を表示しているからです。
解決:
この場合、QSqlQueryModelはQMLからのフィルタリングを可能にするのに十分であるため、QSqlTableModelを使用する必要はありません。したがって、このために、他の回答のモデルを使用できます。したがって、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
}
完全な例はここにあります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加