Vasyl
Vasyl

Reputation: 414

Notify model item when QML List item is clicked

I develop a small qt application using QML. I'd like to show a list of clickable items there. I have IssueHolder class derived from QObject to represent the item to visualize there. I created a model for such items

class IssuesModel : public QAbstractListModel
{
    Q_OBJECT

public:
    IssuesModel(QObject *parent = 0);

    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

    const QList<IssueHolder*>& issues() const { return _issues; }

protected:
    QHash<int, QByteArray> roleNames() const override;

private: //Members
    QList<IssueHolder*> _issues;
};

In the view class I set my model to the qml part like this

 _view = new QQuickView;    
_mainSetModel = new IssuesModel(this);
_view->rootContext()->setContextProperty("mainSetModel", _mainSetModel);

After that I created delegate in my QML file

 ListView {
    // Some properties here

    model: mainSetModel

    delegate: Item {
        // Some properties here

        IssueDelegate {                
            id: issuesDelegate

            // Some properties here

            signal pressed()

            MouseArea {
                onClicked: { issuesDelegate.pressed(); }
            }
        }
    }
}

I'd like to do something when my list item is clicked but I don't want to implement the application logic in QML file. So I'd like to react on delegate click action so that if user click on some item on my list view corresponding IssueHolder instance will be notified. How can I do this?

Upvotes: 0

Views: 842

Answers (1)

Mitch
Mitch

Reputation: 24416

You could declare a IssueHolder role in your model:

enum {
    IssueHolderRole = Qt::UserRole
};

Then, reimplement roleNames():

QHash<int, QByteArray> IssuesModel::roleNames() const
{
    QHash<int, QByteArray> names;
    names.insert(IssueHolderRole, "issueHolder");
    return names;
}

You'll also need to account for the new role in your data() function. The documentation has lots of examples of how to do this, but the gist of it is:

if (role == IssueHolderRole)
    return QVariant::fromValue(_issues.at(index.row()));

In IssueHolder, declare an invokable function or slot:

Q_INVOKABLE void doStuff();

In your delegate, respond to the click:

delegate: Item {
    // Some properties here

    IssueDelegate {                
        id: issuesDelegate

        // Some properties here

        MouseArea {
            onClicked: model.issueHolder.doStuff()
        }
    }
}

Upvotes: 0

Related Questions