kha*_*vah 13 c++ qt combobox qml
我有一个用qml和c ++编写的GUI.有2个组合框(qt control 5.1).只要第一个组合的值发生变化,第二个组合框就必须在运行时更新.
maincontext->setContextProperty("typemodel", QVariant::fromValue(m_typemodel));
maincontext->setContextProperty("unitmodel", QVariant::fromValue(m_unitmodel));
Run Code Online (Sandbox Code Playgroud)
这是我从c ++给qml的两个模型.
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);
}
Run Code Online (Sandbox Code Playgroud)
这是第一个组合框.如您所见,每次更改第一个组合框的值时,第二个组合框的c ++模型都会更新(mainwin.unitGenerator(typebox.currentText)).但它似乎没有更新组合框的模型.
如何在运行时更新qml的模型?
Rei*_*ica 32
为了开始解决您的问题,我们需要了解该unitGenerator方法的作用.如果您使用的是自定义模型,则几乎可以肯定您没有正确实现通知.我此刻的赌注是你没有发信号通知模型重置.
下面是一个完整的代码示例,展示了如何将a绑定QStringListModel到editable ListView和ComboBoxes.第二个ComboBox模型根据第一个模型的选择重新生成.这可能大概是您想要的功能.
注意由角色完成的具体角色处理QStringListModel.该模型将显示和编辑角色视为几乎相同:它们都映射到列表中的字符串值.但是,当您更新特定角色的数据时,dataChanged信号仅包含您已更改的角色.这可以用于破坏模型编辑器项(TextInput)中可能存在的绑定循环.使用自定义模型时,可能需要实现类似的功能.
该display角色用于将组合框绑定到模型.该edit角色用于预填充编辑器对象.编辑器的onTextChanged信号处理程序正在更新display角色,这不会导致绑定循环到自身.如果处理程序正在更新edit角色,则会通过该text属性导致绑定循环.
QML中有各种"模型".在内部,QML将在模型中包含几乎"任何东西".任何内部不是QObject的东西仍然可以是模型(比如说a 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"
}
}
}
Run Code Online (Sandbox Code Playgroud)
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"
Run Code Online (Sandbox Code Playgroud)