Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

ListView not clickable with custom model



  • I have a ListView defined as the following:

    ListView {
        id: mUserGridViewId
        anchors.fill: parent
        //model: mUserPinListModelId
        model: UserPinModel
        width: control.width
        height: control.height
        delegate: userDelegate
    }
    

    The delegate

    Component {
        id: userDelegate
        Item {
           width: parent.width-40
            height: 31
            Rectangle {
                width: parent.width
                height: 30
                y: 1
                color: "green"
                PrimaryText {
                    x: 58
                    text: model.username
                    anchors.verticalCenter: parent.verticalCenter
                }
                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        console.log(username + " clicked")
    	        }
    	    }
            } //Rectangle
        } //Item
    } //Component
    

    The data from the custom model will show in the list but when I click on one of the items, the onClicked() function is not ran. And when I switch from the custom model to a standard ListModel defined in the QML file (like below) I'm able to click on one of the items, and the onClicked() function is ran.

    ListModel {
        id: mUserPinListModelId
    
        ListElement {
            username: qsTr("John")
            pin: 5555
        }
        ListElement {
            username: qsTr("Sally")
            pin: 5555
        }
    }
    

    Since the ListView is clickable using the standard ListModel and not when I switch to the custom model I'm thinking something is wrong with the custom model, but since the data is displayed in seems the custom model is working. No errors on the console. Any ideas on what I should look at?

    EDIT:
    Here is the custom model:

    // The classes defined here describe the ListModel for use in
    // QML on the User Authentication screen selection screen.
    #ifndef USERPINMODEL_H
    #define USERPINMODEL_H
    
    #include <QAbstractListModel>
    #include <QString>
    
    class UserPin
    {
    public:
    	UserPin(const QString username, const uint pin);
    
    	QString username() const;
    	uint pin() const;
    
    private:
    	QString m_username;
    	uint m_pin;
    };
    
    class UserPinModel : public QAbstractListModel
    {
    	Q_OBJECT
    public:
    	enum UserPinRoles {
    		UsernameRole = Qt::UserRole + 1,
    		PinRole
    	};
    
    	UserPinModel(QObject *parent = nullptr);
    
    	void addUserPin(const UserPin &userpin);
    	int rowCount(const QModelIndex & parent = QModelIndex()) const;
    	QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
    
    protected:
    	QHash<int, QByteArray> roleNames() const;
    
    private:
    	QList<UserPin> m_userpin;
    };
    
    #endif // USERPINMODEL_H
    
    #include "userpinmodel.h"
    
    UserPin::UserPin(const QString username, const uint pin)
    	: m_username(username), m_pin(pin)
    {
    }
    
    QString UserPin::username() const { return m_username; }
    uint UserPin::pin() const { return m_pin; }
    
    UserPinModel::UserPinModel(QObject *parent)
    	: QAbstractListModel(parent)
    {
    }
    
    void UserPinModel::addUserPin(const UserPin &userpin)
    {
    	beginInsertRows(QModelIndex(), rowCount(), rowCount());
    	m_userpin << userpin;
    	endInsertRows();
    }
    
    int UserPinModel::rowCount(const QModelIndex & parent) const {
    	Q_UNUSED(parent);
    	return m_userpin.count();
    }
    
    QVariant UserPinModel::data(const QModelIndex &index, int role) const
    {
    	if (index.row() < 0 || index.row() >= m_userpin.count())
    		return QVariant();
    
    	const UserPin &up = m_userpin[index.row()];
    	if (role == UsernameRole)
    		return up.username();
    	else if (role == PinRole)
    		return up.pin();
    	return QVariant();
    }
    
    QHash<int, QByteArray> UserPinModel::roleNames() const {
    	QHash<int, QByteArray> roles;
    	roles[UsernameRole] = "username";
    	roles[PinRole] = "pin";
    	return roles;
    }
    

    Added to the QML environment:

    engine.rootContext()->setContextProperty("UserPinModel", &sessionData.userpinModel);
    


  • You didn't post the code for the custom model so it's impossible to diagnose


  • Qt Champions 2017

    Possible that your model is read-only.



  • Hi @dheerendra,

    How could I check if it is read-only? I don't believe it is. How would a read-only model make it not clickable?



  • Are you sure if you are getting into onClicked slot? Can you put one more console output there without any variables. username can be undefined, for example, thats why you can see nothing.



  • Hi @IntruderExcluder

    I've changed the onClicked to the following and do not get anything, so it does not appear to be making it into the onClicked slot.

    onClicked: {
        console.log(">> CLICKED <<")
        console.log(username + "clicked")
    }
    


  • Hi @mjohn ,i guess the parent of ListView is disabled, if possible can you show us the complete qml code.
    I just copy pasted your code and inserted elements to the model, it seems to be working fine.

    Sample Output:-
    eb36cc78-c0bc-4be7-920b-5dd5b2a12ca9-image.png

    Console:-
    8e29b65b-8ff7-49a3-83b7-ddf0cd3ab03c-image.png


  • Moderators

    @mjohn said in ListView not clickable with custom model:

    ListView {
    id: mUserGridViewId
    anchors.fill: parent
    //model: mUserPinListModelId
    model: UserPinModel
    width: control.width
    height: control.height
    delegate: userDelegate
    }

    SO only thing that jumps directly to my mind is, don't use anchors.fill and width/height definition.

    I had this where this lead to strange behavior of my component



  • Hi @Shrinidhi-Upadhyaya

    Here is the qml for this screen:

    import QtQuick 2.9
    import QtQuick.Controls 2.2
    import QtQuick.Layouts 1.3
    
    import MidmarkTheme 1.0
    import MidmarkControls 1.0
    
    Rectangle {
    	Rectangle {
    		id: contentFrameId
    		x: 20
    		y: 20
    		width: 710
    		height: 390
    
    		ListModel {
    			id: mUserPinListModelId
    
    			ListElement {
    				username: qsTr("John")
    				pin: 5555
    			}
    			ListElement {
    				username: qsTr("Sally")
    				pin: 5555
    			}
    			ListElement {
    				username: qsTr("Bill")
    				pin: 5555
    			}
    			ListElement {
    				username: qsTr("Sandy")
    				pin: 5555
    			}
    			ListElement {
    				username: qsTr("Ann")
    				pin: 5555
    			}
    			ListElement {
    				username: qsTr("Joe")
    				pin: 5555
    			}
    			ListElement {
    				username: qsTr("Andy")
    				pin: 5555
    			}
    			ListElement {
    				username: qsTr("Jim")
    				pin: 5555
    			}
    			ListElement {
    				username: qsTr("Sherry")
    				pin: 5555
    			}
    			ListElement {
    				username: qsTr("Rose")
    				pin: 5555
    			}
    			ListElement {
    				username: qsTr("Mary")
    				pin: 5555
    			}
    			ListElement {
    				username: qsTr("Jay")
    				pin: 555
    			}
    		}
    
    
    		Component {
    			id: userDelegate
    			Item {
    				width: parent.width-40
    				height: 31
    				// Break line
    				Rectangle {
    					width: parent.width
    					height: 1
    					y: 0
    					color: "#000000"
    				}
    				// User area
    				Rectangle {
    					width: parent.width
    					height: 30
    					y: 1
    					color: "transparent"
    					enabled: true
    
    					Text {
    						x: 58
    						text: model.username
    						anchors.verticalCenter: parent.verticalCenter
    					}
    					MouseArea {
    						anchors.fill: parent
    						onClicked: {
    							console.log(">> CLICKED <<")
    							console.log(username + " clicked")
    						}
    					}
    				}
    			}
    		}
    
    		Item {
    			id: mUserItemId
    			width: parent.width - 30
    			height: parent.height - 50
    			x: 20
    			y: 60
    			clip: true
    
    			ScrollView {
    				id: control
    				width: parent.width
    				height: parent.height
    				clip: true
    
    				ScrollBar.vertical: VertScrollBar {
    					parent: control
    					x: control.width - width
    					y: control.topPadding
    					height: control.availableHeight
    				}
    
    				ListView {
    					id: mUserGridViewId
    					//anchors.fill: parent
    					//model: mUserPinListModelId
    					model: UserPinModel
    					//width: control.width
    					//height: control.height
    					delegate: userDelegate
    					enabled: true
    				}
    			}
    		}
    	}
    
    	StackView.onActivated: {
    		console.log("AuthUsrPin: activated")
    	}
    }
    
    

Log in to reply