从 C++ 更改 QML Listview 委托
Posted
技术标签:
【中文标题】从 C++ 更改 QML Listview 委托【英文标题】:Change QML Listview delegate from C++ 【发布时间】:2017-01-21 17:41:57 【问题描述】:我正在尝试从 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】:我认为有更好的方法来做到这一点。
步骤:
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);
【讨论】:
谢谢,但问题是我在单独的 qml 文件中有多个委托,在我的应用程序中有很多屏幕,每个屏幕都有不同的列表视图 UI,我想要的是:传递委托文件C++ 函数的名称 >>> C++ 函数设置 listView 的委托属性(或类似的东西) >>> listview 加载相应的委托。 记住:总是callsetContextProperty
BEFORE setSource
,否则会报错listmodel is not defined【参考方案2】:
必须将属性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
【讨论】:
【参考方案3】:谢谢大家,我刚刚想出了一个使用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"));
How to invoke qml javascript method
【讨论】:
以上是关于从 C++ 更改 QML Listview 委托的主要内容,如果未能解决你的问题,请参考以下文章
如何从 QML 中的 GridView 或 ListView 获取实例化的委托组件
为什么QML ListView委托不立即对选择更改做出反应?