Listview delegate using Loader gives null element



  • Hi everyone,

    I am using a ListView that is supposed to display different type of data so it needs different delegates according to data's type.
    What I did is that the delegate is a Loader that will load a component based on the type of the data. This works well but every time I remove an item from the model ( a custom QAbstractListModel ) I get a Cannot read property 'X' of null. This does not happen if I don't use a Loader but the same delegate for every type of data.

    Does anyone have a suggestion for me ?
    I do follow the beginInsertRows...endInsertRows scheme in the model.



  • hey, do you access the ListView from the delegate? I had some problems when accessing the ListView via the "parent" property, because when you remove an item from the ListView the delegate item might be detached and the "parent" will be "null" until the item is destroyed.. so it might trigger a parent changed signal and you get an "cannot read property 'X' of null" error.. if that makes any sense :)

    solution in my case, just reference the ListView via the id, and not "parent".



  • Nop that is not it, nothing references to the ListView as parent instead of the id.

    Here how it is:

    @
    ListView
    {
    id: myListView
    model: myCustomModel
    delegate: itemDelegate
    }

    Component
    {
    id: itemDelegate
    Loader
    {
    id: delegateLoader

        property variant myModel: model
        property variant cellIndex: index
    
        height: 100
        width: myListView.width
        sourceComponent:
        {
            switch( model.type )
            {
            case 0:
                 firstDelegate
                 break
            case 1:
                  secondDelegate
                   break
            }
        }
    }
    

    }

    Component
    {
    id: firstDelegate
    Text
    {
    text: myModel.text
    }
    }

    Component
    {
    id: secondDelegate
    Image
    {
    source: myModel.image
    }
    }
    @

    When removing items, it would say in that example cannot read property 'image' of null or cannot read property 'text' of null



  • Ok then, I have another idea. Have you tried setting the delegate directly, and not the loader as the delegate? e.g.
    @
    Loader {
    ...
    onLoaded: myListView.delegate = item // loaded item
    }
    @
    I haven't tested this but it should be possible to set the delegate like this?



  • This would not work because Loader is called whenever the ListView encounters a row in its model because that Loader is set as the delegate. So calling myListView.delegate = item does nothing but change the delegate and so invalidate the whole thing ;)

    It has something to do with values binded because of the Loader because it does not happen if I set firstDelegate as myListView's delegate.



  • I'm a bit of a newbie to QML so forgive me if I'm off-beam, but couldn't you simply say:

    @source: myModel == null ? "" : myModel.image@



  • It does work ( I at least get rid of all the warnings ), but I don't find that solution really clean since if myModel is null then nothing should be loaded ..


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.