Important: Please read the Qt Code of Conduct -

Dynamically change a component

  • I have a model displayed in QML. It works with both GridView and ListView separately. I want to be able to switch between a gridView-based display and a listView-based display when I click on a button. Something like :

    Item {
        id: root
        GridView {
            model: m
            delegate: Text { text: "foo" }
        Rectangle {
            id: button
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    /* ???????????????
                       if GridView is displayed :
                           remove GridView and add ListView
                       if ListView is displayed :
                           remove ListView and add GridView
                       ??????????????? */

    I think having both GridView and ListView and setting visible property of only one to true might works but it doesn't look like a way to go to me. This is not the first time I'm facing the problem and I might endup using it in some other more complex cases so I don't want a trick that works in this specific example but more likely a generic of dynamically loading/unloading components in QML.

  • Moderators

    a possibility would be to use Qt.createComponent() or Qt.createQmlObject() methods (what fits better for your needs) to toggle the views. You can store the object also in a property to keep accessible later on.
    Make sure to call destroy() on the old object to remove it.

    Or the "lazy" way: Use a stack-view element, put the layouts init and assign the model to both, and just switch the index on it. This has the disadvantage that both layouts are instantiated. But the advantage that switching between them is faster. Since the object creation/destruction is obsolete.

  • @MoaMoaK
    @raven-worx said in Dynamically change a component:

    Or the "lazy" way: Use a stack-view element

    ...or StackLayout which is simpler and meant for these kind of use cases more than StackView.

  • May be you could simply put your GridView and ListView into the separate files and then show them in Loader? Just change its ".source" when you feel like... Worked for me.

  • Ok, nice, these three answers (StackView / StackLayout / Loader + Component) were what I was looking for. I tried each one and I think I'll stick with the StackView and the replace method as it's easy to have a fading transition with it. And I've already found a use to improve my code for the Loader so I also thank you for that.
    Thx for the help.