Important: Please read the Qt Code of Conduct -

Get index of the clicked element in QML GridView

  • Hi everyone,
    I've a class (PLModel) subclassing QAbstractItemModel and passed to a QML GridView through context. The display works fine. Now i want to invoke a custom method in my PLModel when an element is clicked on. Here is the code i've come up with :

    plmodel.hpp (simplified)

    class PLModel : public QAbstractItemModel
    public : 
        // Constructor
        // Subclassing QAbstractItemModel
        QVariant data( const QModelIndex &index, const int role ) const Q_DECL_OVERRIDE;
        bool setData( const QModelIndex &index, const QVariant & value, int role = Qt::EditRole ) Q_DECL_OVERRIDE;
        int rowCount( const QModelIndex &parent = QModelIndex() ) const Q_DECL_OVERRIDE;
        Qt::ItemFlags flags( const QModelIndex &index ) const Q_DECL_OVERRIDE;
        QModelIndex index( const int r, const int c, const QModelIndex &parent ) const Q_DECL_OVERRIDE;
        QModelIndex parent( const QModelIndex &index ) const Q_DECL_OVERRIDE;
        //The function i want to invoke
        Q_INVOKABLE virtual void activateItem( const QModelIndex &index ) Q_DECL_OVERRIDE;
        // Irrelevant stuff

    plmodel.cpp (simplified)

    // Constructor
    PLModel::PLModel() { }
    // Subclassing QAbstractItemModel
    QVariant PLModel::data( const QModelIndex &index, const int role ) const { ... }
    bool PLModel::setData( const QModelIndex &index, const QVariant & value, int role ) { ... }
    int PLModel::rowCount( const QModelIndex &parent ) const { ... }
    Qt::ItemFlags PLModel::flags( const QModelIndex &index ) const { ... }
    QModelIndex PLModel::index( const int row, const int column, const QModelIndex &parent ) { ... }
    QModelIndex PLModel::parent( const QModelIndex &index ) const { ... }
    // The function I want to invoke
    void PLModel::activateItem( const QModelIndex &index )
        // Print content for debug
        log_info ( index.row() )
        log_info ( index.column() )
        // Do some stuff about this specific item


    import QtQuick 2.0
    Item {
        width: 1000
        height: 1000
        GridView {
            id: gridView
            anchors.fill: parent
            cellWidth: 150
            cellHeight: 150
            model: m     //The model passed through context
            delegate: Item {
                x: 5
                height: 50
                Image {
                    anchors.horizontalCenter: parent.horizontalCenter
                    id: image
                    width: 100
                    height: 100
                    source: model.image
                    MouseArea {
                        anchors.fill: image
                        /* Where i invoke the method */
                        onClicked: m.activateItem(index)

    So my problem is that everytime i clicked on an item in the UI (no matter which one), the index has row=-1 and column=-1 so i don't know in the C++ code which item was clicked. I don't understand why. Am i doing something wrong ? Or is there another way to do what i want to do ?


  • Moderators

    index attached role is not a QModelIndex - it is an integer. That is because QML does not support table data. More info here.

    So you can either calculate the correct item from index (based on amount of columns you have), or provide a model role and then react to that in setData(). For example:

    // QML
    MouseArea {
      onClicked: myCustomRole = 1
    // C++
      if (role == myCustomRole) {
        // ignore the QVariant value, it is irrelevant in this case

  • Ok thx that works like a charm. Both solutions.

Log in to reply