import QtGraphicalEffects 1.0 import QtQuick 2.7 import QtQuick.Controls 2.4 import QtQuick.Controls.Material 2.0 import QtQuick.Layouts 1.3 ColumnLayout { id: root MouseArea { anchors.fill: parent onClicked: { forceActiveFocus() } } MyProfile{ // CURRENT PROFILE INFO AND CONTROL BAR id: myprof } Flickable { // THE ACTUAL CONTACT LIST id: sv //Layout.alignment: Qt.AlignLeft | Qt.AlignTop clip: true Layout.minimumHeight: 100 //Layout.maximumHeight: parent.height - 30 Layout.fillHeight: true Layout.minimumWidth: parent.width Layout.maximumWidth: parent.width contentWidth: colContacts.width contentHeight: colContacts.height boundsBehavior: Flickable.StopAtBounds maximumFlickVelocity: 400 ScrollBar.vertical: ScrollBar { policy: ScrollBar.AlwaysOn } ColumnLayout { id: colContacts width: root.width spacing: 0 Connections { // ADD/REMOVE CONTACT ENTRIES target: gcd onAddContact: function(handle, displayName, image, server, badge, status, trusted, blocked, loading) { contactsModel.append({ "_handle": handle, "_displayName": displayName + (blocked ? " (blocked)" : "" ), "_image": image, "_server": server, "_badge": badge, "_status": status, "_trusted": trusted, "_blocked": blocked, "_loading": loading, "_loading": loading }) } onRemoveContact: function(handle) { for(var i = 0; i < contactsModel.count; i++){ if(contactsModel.get(i)["_handle"] == handle) { console.log("deleting contact " + contactsModel.get(i)["_handle"]) contactsModel.remove(i) return } } } } ListModel { // CONTACT OBJECTS ARE STORED HERE ... id: contactsModel } Repeater { model: contactsModel // ... AND DISPLAYED HERE delegate: ContactRow { handle: _handle displayName: _displayName image: _image server: _server badge: _badge status: _status trusted: _trusted blocked: _blocked loading: _loading } } } } }