QML 组合框与 QSqlModel
QML Combobox with QSqlModel
我目前在用 QSqlTableModel
填充 QML Combobox
时遇到问题。
示例数据库:
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 |
我想按姓名向 select 客户显示带有 QML Combobox
的表格。
因此,我将组合框模型设置为 QSqlTableModel
和 table="customer"
和 textRole="name"
.
我现在的问题在于将 Combobox.currentindex
设置为数据库中的正确值,当然还要从组合框中读回 selected ID
。
Comboboxes
文档指出,每当组合框填充新模型时,其当前索引设置为 1
。
我尝试使用组合框及其父项的 Component.onCompleted
信号设置当前索引,但 selected 索引始终设置为 1
。
所以我认为我在实施模型或 QML-file.
时可能犯了概念错误
有谁知道何时以及如何使用来自 C++ 模型的给定值预先设置 QML 组合框的建议方法?
我不明白问题是什么,因为你没有提供 MCVE,所以我的回复将尝试显示正确的解决方案。
假设您了解 QSqlTableModel
不能直接在 QML 中使用,但您必须添加与字段对应的角色并覆盖 data()
和 roleNames()
方法。
要获取给定ID
的信息,视图的currentIndex
必须使用模型的data()
方法,所以对应的QModelIndex
和角色必须被创建,在这种情况下,为了简化该任务,我实现了一个函数,该函数给出了行和字段名称 returns 数据。
使用上面的方法我实现了以下class:
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 中找到。
我目前在用 QSqlTableModel
填充 QML Combobox
时遇到问题。
示例数据库:
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 |
我想按姓名向 select 客户显示带有 QML Combobox
的表格。
因此,我将组合框模型设置为 QSqlTableModel
和 table="customer"
和 textRole="name"
.
我现在的问题在于将 Combobox.currentindex
设置为数据库中的正确值,当然还要从组合框中读回 selected ID
。
Comboboxes
文档指出,每当组合框填充新模型时,其当前索引设置为 1
。
我尝试使用组合框及其父项的 Component.onCompleted
信号设置当前索引,但 selected 索引始终设置为 1
。
所以我认为我在实施模型或 QML-file.
有谁知道何时以及如何使用来自 C++ 模型的给定值预先设置 QML 组合框的建议方法?
我不明白问题是什么,因为你没有提供 MCVE,所以我的回复将尝试显示正确的解决方案。
假设您了解 QSqlTableModel
不能直接在 QML 中使用,但您必须添加与字段对应的角色并覆盖 data()
和 roleNames()
方法。
要获取给定ID
的信息,视图的currentIndex
必须使用模型的data()
方法,所以对应的QModelIndex
和角色必须被创建,在这种情况下,为了简化该任务,我实现了一个函数,该函数给出了行和字段名称 returns 数据。
使用上面的方法我实现了以下class:
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 中找到。