A problem about dynamic object management in QML, Please help me!



  • Hi, guys.
    I used the js functions method, which the QML API Documents introduces, to create a ListView object and a ListViewDelegate object dynamically. But QtCreator complain about:
    file:///media/....../componentCreation.js:65: ReferenceError: Can't find variable: pathName

    @var newListViewDelegateComponent
    var newListViewDelegate

    var newListViewComponent
    var newListView

    function createSingleViewObjects(currentIndex) {
    newListViewComponent = Qt.createComponent("PictureListView.qml");
    newListView = newListViewComponent.createObject(qmlEvolutionWindow);

     newListViewDelegateComponent = Qt.createComponent("PictureListViewDelegate.qml");
     newListViewDelegate = newListViewDelegateComponent.createObject(qmlEvolutionWindow);
    
    
    
     if(newListView === null){
         console.log("Error creating new album dialog object.");
     }else{
        newListView.width = qmlEvolutionWindow.width
        newListView.height = qmlEvolutionWindow.height
        newListView.model = pictureModel
        newListView.delegate = newListViewComponent
        newListView.positionViewAtIndex(currentIndex, ListView.Center)
         newListView.z = 1
    

    if(newListViewDelegate === null){
    console.log("Error creating new album dialog object.");
    }else{
    newListViewDelegate.width = newListView.width
    newListViewDelegate.height = newListView.height
    newListViewDelegate.width = newListView.width
    newListViewDelegate.height = newListView.height
    newListViewDelegate.source = pathName
    }

     }@
    

    There is an error in the line newListViewDelegate.source = pathName.

    The "pathName" is a role in the pictureModel which is exposed from C++, and it can't assign to newListViewDelegate.source; but it seems that the pictureModel can be assigned to the newListView.model。 Any advice will be appreciated.



  • You can't do it. pictureName is accessable only in delegate, not outside it. If you want to dynamically change role that delegate should use you can pass role name as string (i.e. "pathName") to some delegate property (let's call it sourcePropertyName) and use it in your delegate as
    @
    source: eval(sourcePropertyName)
    @



  • #Denis Kormalev
    Thank you for your reply...

    mmm... it's a good idea, but it seems it doesn't work in my ps file, and the other errors appear now.

    What I want to do is: dynamically create a ListView object and its ListViewDelegate object using js function, but I try it two days, and always fail. I feel depressed about it, can you give me some guidance?

    here is the PictureListView.qml:

    @import Qt 4.7

    ListView {
    anchors.fill: parent

    orientation: ListView.Horizontal
    keyNavigationWraps:true
    snapMode: ListView.SnapOneItem;
    focus:true
    

    }
    @

    Here is PictureListViewDelegate.qml:
    @Rectangle{

    property alias sourceProperty: listViewPicture.sourceString
    
    Image{
        id:listViewPicture
    
        property  string  sourceString : ""
    
        state: "singleView"
        fillMode: Image.Stretch
        source: eval(sourceString)
        anchors.fill: parent
        smooth: true
        opacity: 1
    

    }
    }
    @
    Here is the js file used to dynamically create a ListView object and its ListViewDelegate object:
    @var newListViewDelegateComponent
    var newListViewDelegate

    var newListViewComponent
    var newListView

    function createSingleViewObjects(currentIndex) {
    newListViewComponent = Qt.createComponent("PictureListView.qml")
    newListView = newListViewComponent.createObject(appWindow);

    newListViewDelegateComponent = Qt.createComponent("PictureListViewDelegate.qml");
    newListViewDelegate = newListViewDelegateComponent.createObject(appWindow);
    
    if(newListViewDelegate === null){
        console.log("Error creating new album dialog object delegate.");
    }else{
        newListViewDelegate.width = newListView.width
        newListViewDelegate.height = newListView.height
        newListViewDelegate.sourceProperty = "pathName"
        console.log(newListViewDelegate.source)
    }
    
    if(newListView === null){
        console.log("Error creating new album dialog object.");
    }else{
        newListView.width = qmlEvolutionWindow.width
        newListView.height = qmlEvolutionWindow.height
        newListView.model = pictureModel
        console.log("list view's picture model has been created.")
        newListView.delegate = newListViewDelegateComponent
        newListView.positionViewAtIndex(currentIndex, ListView.Center)
        console.log("currentIndex is:");
        console.log(currentIndex);
        newListView.z = 1
    }
    

    }
    @

    Here is the main.qml:
    @import Qt 4.7
    import "../../componentCreation.js" as ComponentCreationScript

    Rectangle {
    id:appWindow
    ......
    signal switchToSingleView(int currentIndex)
    onSwitchToSingleView: {ComponentCreationScript.createSingleViewObjects(currentIndex)}
    ......
    }
    @

    QtCreator complain about an error:
    file:///media/....../qml/qml_evolution/PictureListViewDelegate.qml:14: Unable to assign [undefined] to QUrl source
    <Unknown File>:1: ReferenceError: Can't find variable: pathName
    undefined

    The content of that line is :
    source: eval(sourceString)



  • It will not work. Why do you create object of your delegate in js code? New delegate objects will be created by view. You should implement some mechanism of passing name of needed property. For example you can always use some role name for it (in all your models).


Log in to reply
 

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