c++ - How to Use Models with QML? -
i have gui written in qml , c++. there 2 comboboxes (qt control 5.1). second combobox has update @ runtime whenever value of first 1 changed.
maincontext->setcontextproperty("typemodel", qvariant::fromvalue(m_typemodel)); maincontext->setcontextproperty("unitmodel", qvariant::fromvalue(m_unitmodel)); these 2 models give qml c++.
combobox { id: typebox anchors.left: text1.right anchors.leftmargin: 5 signal changed(string newtext) width: 70 height: 23 anchors.top: parent.top anchors.topmargin: 37 model: typemodel oncurrenttextchanged: { mainwin.unitgenerator(typebox.currenttext); } this first combobox. see, c++ model of second combobox updated every time value of first changed (mainwin.unitgenerator(typebox.currenttext)). not seem update combobox's model.
how can update qml's model on runtime?
to begin address issue, we'd need see unitgenerator method does. if you're using custom model, it's you're not correctly implementing notifications. bet @ moment you're not signaling model reset.
below complete code example shows how can tie qstringlistmodel editable listview , comboboxes. second combobox's model regenerated based on selection first one. presumably approximates desired functionality.
note specific handling of roles done qstringlistmodel. model treats display , edit roles same: both mapped string value in list. yet when update particular role's data, datachanged signal carries only role you've changed. can used break binding loop might otherwise present in model editor item (textinput). when use custom model, may need implement similar functionality.
the display role used bind combo boxes model. edit role used pre-populate editor objects. editor's ontextchanged signal handler updating display role, , doesn't cause binding loop itself. if handler updating edit role, cause binding loop via text property.
on models in qml
there various kinds of "models" in qml. internally, qml wrap "anything" in model. internally not qobject yet can still model (say qvariant), won't notifying anything.
for example, "model" based on qvariant wraps int not issue notifications, because qvariant not qobject signal changes.
similarly, if "model" tied property value of class derived qobject, fail emit property change notification signal, won't work.
without knowing model types are, it's impossible tell.
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 model, break 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; (int = 1; <= 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"
Comments
Post a Comment