从 C++ 更改 QML Listview 委托
Change QML Listview delegate from C++
我正在尝试从 C++ 更改 qml listview 的委托,但目前我坚持如何更改代表委托的别名 属性。
更新详情:
我在单独的 qml 文件中有多个委托,在我的应用程序中有很多屏幕,每个屏幕都会有不同的 UI 列表视图,我想要的是:
将委托文件名传递给 C++ 函数 >>> C++ 函数设置 listView 的委托 属性(或类似的东西)>>> listview 加载相应的委托。
我的 qml 文件如下所示:
Item {
id: root
property alias listViewDelegate: listView.delegate
ListView{
id: listView
delegate: MyDelegate{} // I have MyDelegate.qml file, it's working well
model: listModel
}
// List model
MyListModel {
id: listModel
}
}
我尝试使用 setProperty() 方法从 C++ 更改 listViewDelegate 别名,但没有成功(实际上是错误)。
qmlObj->setProperty("listViewDelegate", componentDelegate);
如何实现?或者任何人都可以建议我更好的方法来实现它?谢谢!
我认为有更好的方法。
步骤:
1) 在c++端创建一个模型。
class Model : public QObject {
Q_OBJECT
Q_PROPERTY(qint32 status READ status WRITE setStatus NOTIFY statusChanged)
public:
Model(QObject *parent = Q_NULLPTR);
...
}
2) 通过setContextProperty
将模型对象传给qml
Model model;
engine.rootContext()->setContextProperty("model1", &model);
3) 在 Model.status
上绑定您的 ListView 委托
ListView {
id: listview
anchors.fill: parent
spacing: 20
model: listmodel
delegate: model1.status === 0 ? delegate1 : delegate2
}
4) 现在您可以在 C++ 端通过 setStaus() 更改委托。
model.setStatus(1);
必须将 属性 listViewDelegate 分配给 ListView,这样当您修改 ListViewDelegate 属性 时,ListView 将收到通知并更新委托。
Item {
id: root
property Component listViewDelegate: myDelegate
MyDelegate {
id: myDelegate
}
ListView{
id: listView
delegate: listViewDelegate
model: listModel
}
// List model
MyListModel {
id: listModel
}
}
谢谢大家,我刚刚想出了一个方法,使用javascript,看起来很复杂,但很有效。
我将此 javascript 功能添加到我的根项目中
function loadListViewDelegate(file){
var component = Qt.createComponent(file);
if(component && (component.status === Component.Ready))
{
listView.delegate = component;
return file;
}
return "";
}
然后我从 C++ 调用这个函数,参数是委托 qml 文件。它看起来像这样:
QMetaObject::invokeMethod(qmlObj, "loadListViewDelegate", Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, "delegate_screen_home.qml"));
我正在尝试从 C++ 更改 qml listview 的委托,但目前我坚持如何更改代表委托的别名 属性。
更新详情: 我在单独的 qml 文件中有多个委托,在我的应用程序中有很多屏幕,每个屏幕都会有不同的 UI 列表视图,我想要的是:
将委托文件名传递给 C++ 函数 >>> C++ 函数设置 listView 的委托 属性(或类似的东西)>>> listview 加载相应的委托。
我的 qml 文件如下所示:
Item {
id: root
property alias listViewDelegate: listView.delegate
ListView{
id: listView
delegate: MyDelegate{} // I have MyDelegate.qml file, it's working well
model: listModel
}
// List model
MyListModel {
id: listModel
}
}
我尝试使用 setProperty() 方法从 C++ 更改 listViewDelegate 别名,但没有成功(实际上是错误)。
qmlObj->setProperty("listViewDelegate", componentDelegate);
如何实现?或者任何人都可以建议我更好的方法来实现它?谢谢!
我认为有更好的方法。
步骤:
1) 在c++端创建一个模型。
class Model : public QObject {
Q_OBJECT
Q_PROPERTY(qint32 status READ status WRITE setStatus NOTIFY statusChanged)
public:
Model(QObject *parent = Q_NULLPTR);
...
}
2) 通过setContextProperty
将模型对象传给qmlModel model;
engine.rootContext()->setContextProperty("model1", &model);
3) 在 Model.status
上绑定您的 ListView 委托ListView {
id: listview
anchors.fill: parent
spacing: 20
model: listmodel
delegate: model1.status === 0 ? delegate1 : delegate2
}
4) 现在您可以在 C++ 端通过 setStaus() 更改委托。
model.setStatus(1);
必须将 属性 listViewDelegate 分配给 ListView,这样当您修改 ListViewDelegate 属性 时,ListView 将收到通知并更新委托。
Item {
id: root
property Component listViewDelegate: myDelegate
MyDelegate {
id: myDelegate
}
ListView{
id: listView
delegate: listViewDelegate
model: listModel
}
// List model
MyListModel {
id: listModel
}
}
谢谢大家,我刚刚想出了一个方法,使用javascript,看起来很复杂,但很有效。
我将此 javascript 功能添加到我的根项目中
function loadListViewDelegate(file){
var component = Qt.createComponent(file);
if(component && (component.status === Component.Ready))
{
listView.delegate = component;
return file;
}
return "";
}
然后我从 C++ 调用这个函数,参数是委托 qml 文件。它看起来像这样:
QMetaObject::invokeMethod(qmlObj, "loadListViewDelegate", Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, "delegate_screen_home.qml"));