QML Combobox с QSqlModel
Я в настоящее время сталкиваюсь с проблемами с заполнением QML Combobox
с QSqlTableModel
,
Пример базы данных:
Table Customer Table Project
| id | name | | id | name | fk_customer |
|........|..........| |........|.........|...............|
| 1 | name1 | | 1 | pro1 | 1 |
| 2 | name2 | | 2 | pro2 | 1 |
| 3 | name3 | | 3 | pro3 | 3 |
Я хочу показать форму с QML Combobox
выбрать клиента по имени.
Поэтому я устанавливаю модель комбинированного списка на QSqlTableModel
с table="customer"
а также textRole="name"
,
Моя проблема теперь заключается в настройке Combobox.currentindex
к правильному значению из базы данных и, конечно, прочитать selected ID
назад из выпадающего списка.Comboboxes
В документации говорится, что всякий раз, когда выпадающий список заполняется новой моделью, его текущий индекс устанавливается равным 1
,
Я пытался установить текущий индекс с помощью Component.onCompleted
Сигнал из выпадающего списка и его родителя, но выбранный индекс всегда был установлен на 1
,
Так что я думаю, что, возможно, сделал концептуальную ошибку при реализации модели или QML-file.
Кто-нибудь знает предложенный способ, когда и как предварительно установить Combobox QML с заданным значением из модели C++?
1 ответ
Я не понимаю, в чем проблема, поскольку вы не предоставляете MCVE, поэтому в моем ответе я попытаюсь найти правильное решение.
Предполагая, что вы понимаете, что QSqlTableModel
нельзя использовать непосредственно в QML, но вы должны добавить роли, соответствующие полям, и перезаписать data()
а также roleNames()
метод.
Получить информацию о данном ID
currentIndex
зрения должны использовать data()
метод модели, так что соответствующий QModelIndex
и роль должна быть создана, в этом случае, чтобы упростить эту задачу, я реализовал функцию, которая с учетом строки и имени поля возвращает данные.
Используя вышеизложенное, я реализовал следующий класс:
sqltablemodel.h
#ifndef SQLTABLEMODEL_H
#define SQLTABLEMODEL_H
#include <QSqlTableModel>
#include <QSqlRecord>
class SqlTableModel : public QSqlTableModel
{
Q_OBJECT
Q_PROPERTY(QStringList fieldNames READ fieldNames)
public:
using QSqlTableModel::QSqlTableModel;
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=Qt::DisplayRole) 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;
}
Q_INVOKABLE QVariant data(int row, const QString & fieldName){
int col = record().indexOf(fieldName);
if(col != -1 && 0 <= row && row < rowCount()){
QModelIndex ix = index(row, col);
return ix.data();
}
return QVariant();
}
QStringList fieldNames() const{
QStringList names;
for (int i = 0; i < record().count(); i ++) {
names << record().fieldName(i);
}
return names;
}
};
#endif // SQLTABLEMODEL_H
Поэтому вы должны создать модель и экспортировать ее в QML:
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
if(!createConnection()) // open the connection with the DB
return -1;
SqlTableModel model;
model.setTable("Customer");
model.select();
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("cppmodel", &model);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
И соединение сделано в QML:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.4
Window {
visible: true
width: 320
height: 240
title: qsTr("ComboBox with SqlTableModel")
ComboBox {
anchors.centerIn: parent
model: cppmodel
textRole: "name"
Component.onCompleted: currentIndex = 4
onCurrentIndexChanged: {
var id = cppmodel.data(currentIndex, "id");
var name = cppmodel.data(currentIndex, "name");
console.log(qsTr("currentIndex: %1, id: %2, name: %3").arg(currentIndex).arg(id).arg(name))
}
}
}
Полный пример можно найти по следующей ссылке.