Ответ 1
Чтобы даже начать решать вашу проблему, нам нужно посмотреть, что делает метод unitGenerator
. Если вы используете пользовательскую модель, она почти уверена, что вы неправильно выполняете уведомления. Моей ставкой на данный момент было бы то, что вы не сигнализируете модель reset.
Ниже приведен полный пример кода, который показывает, как вы можете связать QStringListModel
с редактируемыми ListView
и ComboBox
es. Вторая модель ComboBox
восстанавливается на основе выбора из первого. Это предположительно приближает желаемую функциональность.
Обратите внимание на конкретную обработку ролей, выполняемых QStringListModel
. Модель рассматривает отображение и редактирование ролей почти одинаково: оба они отображаются в строковое значение в списке. Однако, когда вы обновляете данные конкретной роли, сигнал dataChanged
несет только ту роль, которую вы изменили. Это может быть использовано для разбиения цикла привязки, который может быть представлен в элементе редактора модели (TextInput). Когда вы используете пользовательскую модель, вам может потребоваться реализовать аналогичные функции.
Роль display
используется для привязки полей со списком к модели. Роль edit
используется для предварительного заполнения объектов редактора. Обработчик обработчика редактора onTextChanged
обновляет роль display
, и это не вызывает привязку к себе. Если обработчик обновляет роль edit
, это вызовет цикл привязки через свойство text
.
О моделях в QML
В QML существуют различные "модели". Внутренне QML будет обернуть почти "что угодно" в модели. Все, что внутренне не является QObject, все еще может быть моделью (скажем, QVariant
), ни о чем не будет уведомлять кого-либо.
Например, "модель" на основе QVariant
, которая обертывает int
, не будет выдавать уведомления, потому что QVariant
не является QObject
, который мог сигнализировать об изменениях.
Аналогично, если ваша "модель" привязана к значению свойства класса, полученного из QObject
, но вы не можете emit
передать сигнал уведомления об изменении свойства, он также не будет работать.
Не зная, что такое ваши модели, невозможно сказать.
main.qml
import QtQuick 2.0
import QtQuick.Controls 1.0
ApplicationWindow {
width: 300; height: 300
ListView {
id: view
width: parent.width
anchors.top: parent.top
anchors.bottom: column.top
model: model1
spacing: 2
delegate: Component {
Rectangle {
width: view.width
implicitHeight: edit.implicitHeight + 10
color: "transparent"
border.color: "red"
border.width: 2
radius: 5
TextInput {
id: edit
anchors.margins: 1.5 * parent.border.width
anchors.fill: parent
text: edit // "edit" role of the model, to break the binding loop
onTextChanged: model.display = text
}
}
}
}
Column {
id: column;
anchors.bottom: parent.bottom
Text { text: "Type"; }
ComboBox {
id: box1
model: model1
textRole: "display"
onCurrentTextChanged: generator.generate(currentText)
}
Text { text: "Unit"; }
ComboBox {
id: box2
model: model2
textRole: "display"
}
}
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickWindow>
#include <QStringListModel>
#include <QQmlContext>
class Generator : public QObject
{
Q_OBJECT
QStringListModel * m_model;
public:
Generator(QStringListModel * model) : m_model(model) {}
Q_INVOKABLE void generate(const QVariant & val) {
QStringList list;
for (int i = 1; i <= 3; ++i) {
list << QString("%1:%2").arg(val.toString()).arg(i);
}
m_model->setStringList(list);
}
};
int main(int argc, char *argv[])
{
QStringListModel model1, model2;
Generator generator(&model2);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
QStringList list;
list << "one" << "two" << "three" << "four";
model1.setStringList(list);
engine.rootContext()->setContextProperty("model1", &model1);
engine.rootContext()->setContextProperty("model2", &model2);
engine.rootContext()->setContextProperty("generator", &generator);
engine.load(QUrl("qrc:/main.qml"));
QObject *topLevel = engine.rootObjects().value(0);
QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
window->show();
return app.exec();
}
#include "main.moc"