0
votes

If I have the following:

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2    

ApplicationWindow {
    title: qsTr("Hello World")
    width: 800
    height: 700
    visible: true

    property var myArray: [1, 2, 3, 4, 5, 6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

    menuBar: MenuBar {
        Menu {
            title: qsTr("&File")
            MenuItem {
                text: qsTr("&Open")
                onTriggered: messageDialog.show(qsTr("Open action triggered"));
            }
            MenuItem {
                text: qsTr("E&xit")
                onTriggered: Qt.quit();
            }
        }
    }

    Rectangle {
        id: myButton
        anchors.top: parent.top
        anchors.topMargin: 5
        color: "yellow"
        width: 100
        height: 25
        radius: 3
        anchors.horizontalCenter: parent.horizontalCenter
        Text {
            text: "Clear Selection"
            anchors.fill: parent
            horizontalAlignment: Text.AlignHCenter
            verticalAlignment: Text.AlignVCenter
        }

        MouseArea {
            anchors.fill: parent
            onClicked: {
                myListView.currentIndex = -1
            }
        }
    }

    ListView {
        id: myListView
        width: 300
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.top: myButton.bottom
        anchors.topMargin: 5
        anchors.bottom: parent.bottom
        currentIndex: -1
        //highlightFollowsCurrentItem: false
        highlight: Rectangle {
            color: "pink"
            radius: 3
            width: parent.width - 10
            height: 25
            //y: myListView.currentItem.y
            anchors.horizontalCenter: parent.horizontalCenter
        }
        clip: true
        model: myArray
        delegate: Rectangle {
            width: parent.width - 10
            height: 25
            color: "transparent"
            border.color: "cyan"
            anchors.horizontalCenter: parent.horizontalCenter
            Text {
                text: myArray[index]
                horizontalAlignment: Text.AlignHCenter
                verticalAlignment: Text.AlignVCenter
                anchors.fill: parent
            }

            MouseArea {
                anchors.fill: parent
                onClicked: myListView.currentIndex = index
            }
        }
    }

    MessageDialog {
        id: messageDialog
        title: qsTr("May I have your attention, please?")

        function show(caption) {
            messageDialog.text = caption;
            messageDialog.open();
        }
    }
}

When clicking the Clear Selection button I receive the following:
qrc:/main.qml:67: TypeError: Cannot read property of null
qrc:/main.qml:64: TypeError: Cannot read property of null

How can I clear the selection without getting the error? It doesn't appear to crash the application but I have a list view that changes based on another list view selection and the error occurs several times, cluttering up the debug output in Qt Creator. I have noticed this in Qt 5.4 and 5.5

3
Can you tell us which are lines 64 and 67 respectively?Lajos Arpad
In the highlight anchors.horizontalCenter: parent.horizontalCenter and width: parent.width - 10kmx78

3 Answers

0
votes

The documentation for ListView says:

An instance of the highlight component is created for each list. The geometry of the resulting component instance is managed by the list so as to stay with the current item, unless the highlightFollowsCurrentItem property is false.

So you don't need to try to manage the position of the highlight item yourself. If you want to position the highlight, create an intermediate parent item instead:

highlight: Item {
    Rectangle {
        color: "pink"
        radius: 3
        width: parent.width - 10
        height: 25
        anchors.horizontalCenter: parent.horizontalCenter
    }
}

As for why it happens, it's likely because the highlight item is reparented, leaving it in a state where its parent property is null. You can test this out with the following code:

anchors.horizontalCenter: { print(parent); parent.horizontalCenter }
0
votes

The problem in general is that if you have a foo, which is supposed to have a bar, then you reference it as foo.bar, however, if foo was not properly initialized, then it cannot have a bar, since it does not exist (yet). In your case it seems that parent is not properly initialized, so it does not have a width and horizontalCenter (in the delegate, maybe), respectively. The solution is to initialize properly the object whose members are to be used, in our case, parent.

0
votes

I had asked this question over on the Qt forum (https://forum.qt.io/topic/62328/clearing-a-qml-listview-selection) as well, but stack was quicker with a response. Checking the parent value works:

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2

ApplicationWindow {
    title: qsTr("Hello World")
    width: 800
    height: 700
    visible: true

    property int myMargin: 5

    menuBar: MenuBar {
        Menu {
            title: qsTr("&File")
            MenuItem {
                text: qsTr("&Open")
                onTriggered: messageDialog.show(qsTr("Open action triggered"));
            }
            MenuItem {
                text: qsTr("E&xit")
                onTriggered: Qt.quit();
            }
        }
    }

    Rectangle {
        id: myButton
        anchors.top: parent.top
        anchors.topMargin: myMargin
        color: "yellow"
        width: 100
        height: 25
        radius: 3
        anchors.horizontalCenter: parent.horizontalCenter
        Text {
            text: "Clear Selection"
            anchors.fill: parent
            horizontalAlignment: Text.AlignHCenter
            verticalAlignment: Text.AlignVCenter
        }

        MouseArea {
            anchors.fill: parent
            onClicked: {
                myListView.currentIndex = -1
            }
        }
    }

    Rectangle {
        width: 300
        anchors.top: myButton.bottom
        anchors.topMargin: myMargin
        anchors.bottom: parent.bottom
        anchors.horizontalCenter: parent.horizontalCenter

        ListView {
            id: myListView
            anchors.fill: parent
            currentIndex: -1
            spacing: 3
            highlightMoveDuration: 25
            highlight: Rectangle {
                width: parent ? parent.width - 10 : 0
                height: parent ? 25 : 0
                color: "pink"
                radius: 3
                anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined
            }
            clip: true

            model: ListModel {
                id: myArray
                Component.onCompleted: {
                    for (var i = 1; i < 46; i++)
                        append({number: i})
                }
            }

            delegate: Rectangle {
                width: parent ? parent.width - 10 : 0
                height: parent ? 25 : 0
                color: "transparent"
                border.color: "cyan"
                anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined
                Text {
                    text: number
                    horizontalAlignment: Text.AlignHCenter
                    verticalAlignment: Text.AlignVCenter
                    anchors.fill: parent
                }

                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        myListView.currentIndex = index
                    }
                }
            }
        }
    }

    MessageDialog {
        id: messageDialog
        title: qsTr("May I have your attention, please?")

        function show(caption) {
            messageDialog.text = caption;
            messageDialog.open();
        }
    }
}