2
votes

I have ListView item in QML with custom delegate:

Component{


    id: contactDelegate

    Item
    {
        id: wrapper;
        width: 306; height: 40

        FlipableImage
        {
            id: flipableImage
            width: 30
            height: 30

            anchors.verticalCenter: wrapper.verticalCenter;
            anchors.left:  wrapper.left
            anchors.leftMargin: 10

            frontImage: serverIconSource;
            backImage: "qrc:/images/resources/images/log.png";
        }

        Column
        {
            anchors.left: flipableImage.right
            anchors.leftMargin: 10
            Text
            {
                font.family: helveticaNeueBoldFont.name
                font.pixelSize: 14
                text: serverName;
            }

            Text
            {
                font.family: helveticaNeueFont.name
                font.pixelSize: 14
                text: serverLogin;
            }
        }

        ConnectionStateImage
        {
            id: stateImage
            state: "noState"
            anchors.verticalCenter: parent.verticalCenter;
            anchors.right: wrapper.right
            anchors.rightMargin: 10
            visible: itemMouseArea.containsMouse;
        }

        MouseArea
        {
            id: mouseArea;
            anchors.fill: flipableImage
            hoverEnabled: true;
            z: 1
            onEntered:
            {
                flipableImage.flipped = !flipableImage.flipped;
            }
            onExited:
            {
                flipableImage.flipped = !flipableImage.flipped;
            }
        }
    }
}

on mouse hover flipableImage flipped. But I need to flip it by hand on event from model or from QDeclarativeView. How I can navigate to item in list view to change property of FlipableImage. It's not important for me to navigate from qml or from C++. Thx.

2

2 Answers

2
votes

One of the special properties of the QML list view element is that it only creates delegate items visible at one time. As soon as they move out of the viewport they are destroyed.

Therefore there is no way to know if one particular item representing one a of the source model actually exists at a specific time. That is also reason why there is no itemAt(index) method like the Repeater element has.

The best way to solve you problem is to solve it declaratively in the delegate component itself:

  • remove the explicit assignments to flipableImage.flipped in the mouse area, in fact all the event handlers not needed at all.

  • give the component a boolean property to indicate whether the item is forcefully flipped, assign the value of property in the list view depending on your actual logic. You will have to do that declaratively, too for the reasons outlined above. A good strategy could be to compare the index property against a variable holding the index to something with.

  • and finally compute the flipped state declaratively:

    Item {
         id: wrapper
         property bool manuallyFlipped: false       
         /* ... */
         FlipableImage {
             /* ... */
             flipped: mouseArea.containsMouse || wrapper.manuallyFlipped
         }
         /* ... */
    }
    
1
votes

If I were you I would not hold state of an item in QML delegate. I would derive my own model from QAbstractListModel, expose it from C++ to QML and hold state of any item there. How to expose model is written here. To set value of an item in the list you will have to export to QML C++ methods of your model class, because you won't be able to set item model value by assignment in QML (at least as far as I remember).

MouseArea {
//...
    onEntered {
        myModel.itemAtIndexEntered(currentIndex);
    }
//...
}

To export C++ function to qml you have to make them as slots or add Q_INVOKABLE to their declaration. You can find more details here.