我目前在用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"
的{{1}}。
我的问题现在在于将textRole="name"
设置为数据库中的正确值,当然还要从组合框中读回Combobox.currentindex
。
selected ID
文档指出,每当用新模型填充组合框时,其当前索引都将设置为Comboboxes
。
我试图使用来自组合框及其父级的1
信号设置currentindex,但是所选索引始终设置为Component.onCompleted
。
所以我认为在实现模型或1
有人知道何时以及如何使用c ++模型中的给定值预先设置QML组合框的建议方法吗?
答案 0 :(得分: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))
}
}
}
完整的示例可以在下面的link中找到。