How to prevent a negative index in a Repeater?



  • I have the following code, which uses my own model. Somehow I get a negative index value in the Repeater's delegate.
    The model works correct, printing rowCount is correct and it also shows all elements.
    The bug occurs only with 3 or 4 elements, not with 2.

    Repeater {
        id: repeater
        anchors.fill: parent
    
        model: AvatarShowCaseModel {
            id: avatarModel
        }
    
        // Entry: x, y, scale
        property var positions: [
            // First place
            [ (base.width - elementWidth) / 2.0,     base.height / 2.2,      2.0 ],
            // Second place
            [ (base.width - elementWidth) / 4.0,     base.height / 1.7,      1.5 ],
            // Third place
            [ (base.width - elementWidth) / 1.3,     base.height / 1.7,      0.7 ],
            // empty dummy, 4th place not show yet (he is going to wipe the floor)
            [ 0, 0, 0 ],
            [ 0, 0, 0 ], ]
    
        delegate: Item {
            width:  elementWidth
            height: elementHeight
    
            Component.onDestruction: console.log( index )
    
            x:     repeater.positions[ index ][0]
            y:     repeater.positions[ index ][1]
            scale: repeater.positions[ index ][ 2 ]
    
            visible:  index < 3
            Image {
                anchors.fill: parent
                source: imagePath
            }
        }
    }


  • @c64zottel It may be important to know what AvatarShowCaseModel actually is. Is it written in C++?



  • Yes, it is a C++ model:

    AvatarShowCaseModel::AvatarShowCaseModel(QObject *parent) : QAbstractListModel(parent)
    {
        connect( GC_instance, SIGNAL(avatarsUpdated()), SLOT(avatarsUpdated()) );
    }
    
    void AvatarShowCaseModel::createAvatar()
    {
        int s = GC_instance->avatars().size();
        beginInsertRows(QModelIndex(), s, s );
        GC_instance->registerPlayer( true );
        endInsertRows();
    
        setPlayerNumber( GC_instance->avatars().size() );
    }
    
    void AvatarShowCaseModel::removeAvatar(int id)
    {
        beginResetModel();
        GC_instance->unRegisterPlayer( id );
        endResetModel();
    
        setPlayerNumber( GC_instance->avatars().size() );
    }
    
    
    int AvatarShowCaseModel::rowCount(const QModelIndex &index) const
    {
        Q_UNUSED(index)
        qDebug() <<  GC_instance->avatars().size();
        return GC_instance->avatars().size();
    }
    
    QVariant AvatarShowCaseModel::data(const QModelIndex & index, int role) const
    {
        QVector<Avatar *> avatars( GC_instance->avatars() );
        int row = index.row();
    
        Avatar * avatar = 0;
        if( row < avatars.size() && row < MAX_AVATARS )
            avatar = avatars[ row ];
    
    
        switch( role ) {
        case Roles::imagePath:
            return avatar->sideImage();
        case Roles::localPlayer:
            return QVariant( avatar->isLocal() );
        case Roles::avatarId:
            return QVariant( avatar->id() );
        }
        return QVariant();
    }
    
    SGETTER_PROPERTY( AvatarShowCaseModel, setPlayerNumber, int, playerNumber )
    
    QHash<int, QByteArray> AvatarShowCaseModel::roleNames() const
    {
        QHash<int, QByteArray> roles;
        roles[ Roles::imagePath ]   = "imagePath";
        roles[ Roles::localPlayer ] = "localPlayer";
        roles[ Roles::avatarId ]    = "avatarId";
    
        return roles;
    }
    
    void AvatarShowCaseModel::avatarsUpdated()
    {
        beginResetModel();
        endResetModel();
    }
    

Log in to reply