Add object to QAbstractListmodel-derived model from QML
-
Hi,
Check if "this":http://qt-project.org/forums/viewthread/45795/#188768 helps you. Check the function void FileModele::addItem(QString filename) in filemodel.cpp. It is Q_INVOKABLE and is called from QML which adds an item to the ListView and also creates an object of type File.
Is this what you are looking for ? -
Hi p3c0,
That thread is interesting and helpful, but it doesn't quite cover my case. In the thread, heikkik is passing a string, whereas I would like to pass an object.
As I mentioned, I have defined addGame() and addGame(Game*) in my model, both as Q_INVOKABLE. I can oly call addGame() successfully, whereas addGame(Game*) always receives a null pointer.
The second issue I have is that I have no clue how to modify the contents of GameModel from outside the delegate, or even accessing their properties.
-
But does your QML have access to the Game class ?
bq. The second issue I have is that I have no clue how to modify the contents of GameModel from outside the delegate, or even accessing their properties.
AFAIk, you must have added the modle using setContextProperty so that object should be available from all QML files.
-
Yes. Please see my second post in this thread. Both Game and GameModel are registered with qmlRegisterType() and an instance of the model is available through setContextProperty().
-
IMO, then you need the initialise Game too in QML just as you have done for GameModel and then pass it's id to the addGame().
-
Ok, but since I don't know how many times the user is going to click the "New Game" button, I can't initialise it with static code like this:
@Game {
id: something
name: "Of the game"
}@So what I need is the QML equivalent of the following C++ code:
@Game g("Name of the game");
// OR
Game* g = new Game("Name of the game");
@It's completely unclear to me how I do that. Naturally, I could bite the bullet and accept that I need to create the object in C++ and pass the new name, but it seems a bit restricted.
-
Not sure, but i think one way to create the Game object dynamically would be through "Component":http://qt-project.org/doc/qt-5/qml-qtqml-component.html and using "createObject":http://qt-project.org/doc/qt-5/qml-qtqml-component.html#createObject-method and then may be you could pass that object to addGame().
What would be the restrictions you think if you go thru c++ way ?
-
Well, perhaps mainly that the interface to create a new Game is restricted to passing strings to C++.
Also, since I haven't found a way of accessing the elements of the model outside the delegate, I'm unable to manipulate them. I have tried defining an at() method, returning a Game pointer, but this seems unusable in QML.
-
But you can do the business logic in c++ and the QML for just the view.
-
Yep, I guess you're right. I'm still absorbing the philosophy of QML. The way ListView works clearly decouples the business logic.
Nonetheless, I'm struggling to see how I can achieve some things in the presentation layer without accessing the elements in the list somehow. Any tips on how to achieve an at()-like method?
-
Now going through your original way,
- Registering the Game.
- Embed Game in "Component":http://qt-project.org/doc/qt-5/qml-qtqml-component.html.
- Create the Game object dynamically using "createObject":http://qt-project.org/doc/qt-5/qml-qtqml-component.html#createObject-method
- Then store that object in an array . For eg.
@
Component {
id: component
Game {}
}
property var gameArray: []
var obj = component.createObject(myGame)
gameArray.push(obj)
@- Then access it,
@
var obj = gameArray[index]
console.log(obj.color)
@
Edited
-
Thanks, p3c0!
I haven't time to try that for a few days, but it seems workable. Mind you, I'm not sure I follow the logic in the accessing code:
@var obj = array[gameArray]@Shouldn't that be? ...
@var obj = gameArray[some_index]@ -
Oh Sorry for the typo. Thanks for pointing out. I've now edited the original post.