Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manipulate data in a QAbstractListModel from a QML ListView

Tags:

c++

qt

qt4

qml

qt4.8

I have a QML ListView which uses a QAbstractListModel subclass as a model.

ListView {
    id: myListView
    x: 208
    y: 19
    width: 110
    height: 160
    delegate: myListDelegate {}
    model: MyListModel
    opacity: 0
}

The model is a list of MyListItems.

class MyListModel : public QAbstractListModel
{
    Q_OBJECT
public:
    enum MyRoles {
        HeadingRole = Qt::UserRole + 1,
        DescriptionRole,
        QuantityRole
    };

    explicit MyListModel(QObject *parent = 0);

    void addMyListItem(const MyListItem &item);
    int rowCount(const QModelIndex & parent = QModelIndex()) const;
    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
    void dropList();

private:
    QList<MyListItem> m_list;

};

In the delegate I have a mousearea.

How I can intercept a click on the mousearea and pick that MyListItem from my QList model and send it somewhere inside the C++ part of the application?

like image 981
Zhigalin - Reinstate CMs Avatar asked Jun 27 '17 10:06

Zhigalin - Reinstate CMs


1 Answers

You can also use index property in the delegate to manipulate the data. You just need to transform the QML index into a QModelIndex using the index method on your model. Here's a simple example where we change the display value to the string "3" every time a list item gets clicked.

ListView {
    id: listView
    anchors.fill: parent
    model: my_model

    delegate: Rectangle {
        height: 50
        width: listView.width

        MouseArea {
            anchors.fill: parent
            onClicked: {
                // Column is always zero as it's a list
                var column_number = 0; 
                // get `QModelIndex`
                var q_model_index = my_model.index(index, column_number);

                // see for list of roles: 
                // http://doc.qt.io/qt-5/qabstractitemmodel.html#roleNames
                var role = 1

                var data_changed = my_model.setData(q_model_index, "3", role);

                console.log("data change successful?", data_changed);
            }
        }
    }
}

In addition to the index property in the delegates, all of the default role names are available in the delegates. So for example, I've used the decoration role to set the color property of my Rectangle delegate before. See this list for more.

ListView {
    delegate: Rectangle {
        // list items have access to all default `roleNames` 
        // in addition to the `index` property.
        // For example, using the decoration role, demo'd below
        color: decoration
    }
}

Please also see this link where Mitch Curtis recommends using qmlRegisterUncreatableType to register user enums.

like image 152
Ben Hoff Avatar answered Sep 17 '22 20:09

Ben Hoff