Reputation: 103
I am trying to change the delegate of qml listview from C++ but currently I stuck at how to change the alias which represents the delegate property.
Update on details: I have multiple delegates in separated qml files, in my application there are many screens, each screen will have different UI of listview, what I want is something like:
Pass delegate file name to C++ function >>> C++ function set delegate property of listView (or thing like that) >>> listview loads corresponding delegate.
My qml file looks like:
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
}
}
I tried to change listViewDelegate alias from C++ using setProperty() method but got no luck (error in fact).
qmlObj->setProperty("listViewDelegate", componentDelegate);
How to achieve this? Or anyone can suggest me the better method to achieve it? Thanks!
Upvotes: 1
Views: 2223
Reputation: 103
Thank everyone, I just figured out a way to do that by using javascript, seems complicated but it works.
I add this javascript function into my root Item
function loadListViewDelegate(file){
var component = Qt.createComponent(file);
if(component && (component.status === Component.Ready))
{
listView.delegate = component;
return file;
}
return "";
}
Then I invoke this function from C++, with parameter is the delegate qml file. It looks like this:
QMetaObject::invokeMethod(qmlObj, "loadListViewDelegate", Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, "delegate_screen_home.qml"));
How to invoke qml javascript method
Upvotes: 0
Reputation: 2168
The property listViewDelegate has to be assigned to the ListView, so that when you modify the ListViewDelegate property, the ListView will be notified of this and update the delegate.
Item {
id: root
property Component listViewDelegate: myDelegate
MyDelegate {
id: myDelegate
}
ListView{
id: listView
delegate: listViewDelegate
model: listModel
}
// List model
MyListModel {
id: listModel
}
}
Upvotes: 2
Reputation: 463
I think that there is a better way to do this.
Steps:
1) create a model in c++ side.
class Model : public QObject {
Q_OBJECT
Q_PROPERTY(qint32 status READ status WRITE setStatus NOTIFY statusChanged)
public:
Model(QObject *parent = Q_NULLPTR);
...
}
2) pass the Model Object to qml by setContextProperty
Model model;
engine.rootContext()->setContextProperty("model1", &model);
3) binding your delegate of ListView on Model.status
ListView {
id: listview
anchors.fill: parent
spacing: 20
model: listmodel
delegate: model1.status === 0 ? delegate1 : delegate2
}
4) now you can change delegate by setStaus() in c++ side.
model.setStatus(1);
Upvotes: 4