0

Summary

QML Swipeview has problems updating when model of repeater is reset. The Qt version is 5.12.

Description

Following the doc in (https://doc.qt.io/qt-5/qml-qtquick-controls2-swipeview.html) a SwipeView is implemented. Difference with the example stated in the link, is that no Loader is used. The model of the Repeater is injected by the parent view in form of a QAbstractListModel.

When the viewModel is reset, the SwipeView has problems to update. It causes several repaints of the first page. For the user this appears as if the views is flickering. In the following the QML file and update function of the QAbstractListModel is described.

QML File:

Item {
    id: root

    /**
      Set the model (is of type QAbstractListModel
      **/
    property var viewModel

    height: 30  * Screen.pixelDensity
    width: 60 * Screen.pixelDensity

    Rectangle {
        id: wrapper
        anchors.fill: parent
        color: "grey"

        SwipeView {
            id: swipe
            clip: true
            anchors.fill: parent

            Repeater {
                model: root.viewModel

                Rectangle {
                    width: 20
                    height: 20
                    border.color: "black"
                    border.width: 1

                    Text {
                        text: index
                    }
                }
            }
        }
    }
}

Update Function:

void DerivedQAbstractList::setPages(const std::vector<Pages> &pages)
{
    beginResetModel();

    // create internal data structure
    
    endResetModel();
}

Observations:

  1. Update problem does not appear when the QAbstractList model is initially empty.
  2. Using the Repeater without a SwipeView works fine (e.g. Column {Repeater {...}}

Do you have any ideas what could be the problem. Or give me an alternative approach to have a swiping view with dynamical model?

Edit 1.0. Using a Instantiator As asked in the comment, we tried to replace the Repeater with an Instantiator. We can see from the console log, that the components are created. However they do not appear on the screen. What do we miss?

    Rectangle {
        id: wrapper
        anchors.fill: parent
        color: "grey"

        SwipeView {
            id: swipe
            clip: true
            anchors.fill: parent

            Instantiator {
                model: root.viewModel

                delegate: Rectangle {
                    Component.onCompleted: console.log("Created")
                    width: 20
                    height: 20
                    border.color: "black"
                    border.width: 1

                    Text {
                        text: index
                    }
                }
            }
        }
    }
Adso4
  • 111
  • 3
  • 10
  • I'm curious if you get the same problem swapping the Repeater with an Instantiator and setting asynchronous to true? – JarMan Oct 30 '20 at 20:32
  • @JarMan I have added this solution to the question. We could not get it to work. Do you see if something is missing? – Adso4 Nov 02 '20 at 07:22
  • Oh, with an Instantiator, you need to manually set the visual parent. So inside your `Rectangle`, add this: `parent: swipe`. – JarMan Nov 02 '20 at 14:14

0 Answers0