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 { Q_OBJECT public : // Constructor PLModel() // 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 .... }
ui.qml
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 ?
Thx
-
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++ setData() { if (role == myCustomRole) { // ignore the QVariant value, it is irrelevant in this case activateItem(index); } }