derM
derM

Reputation: 13701

Resolve Integer-Role to RoleName in QML

In QML, a models roles are usually used by their names as strings.
However in some cases, this is not so. An example is the ListModel.onDataChanged

Here we have three arguments (see here) topLeft, bottomRight and roles that we can use to handle the signal. While you can use the topLeft.row easily to determine the index, I found no way to usefully evaluate the roles, that are given as a QVector<int>, while for the QML-usage a QVector<string> would be advantageous. To make things worse, roleNames, available in C++ returning the mapping of the integer-representation of the role to the respective string representing the role name.

Luckily I have only a limited amount of roles, so I might handle it. But it would be really nice of QML to give me the information I so desperately seek. ;-)

So maybe you have a solution that does not need C++ (I might create a ProxyModel that then exposes the roleNames() for me)

Upvotes: 0

Views: 2184

Answers (2)

derM
derM

Reputation: 13701

After some more studying of the C++-code of the ListModel I came to the conclusion, that this is not possible without access to the C++-Layer.

But as I planned on using the QML ListModels for the prototyping, I decided to simply register a QIdentityProxyModel-descendant, which I extended by a method:

QString ProxyModel::getRoleIntToName(int roleID) const
{
    return (QString)(roleNames()[roleID]);
}

Now, whenever I need to have access to the C++-layer of a QML-model, I can put it into this ProxyModel, and retrive all information that might have been hidden to QML.

Upvotes: 1

Adversus
Adversus

Reputation: 2236

Are you sure you need this, i.e. using the exposed role as a property in QML does not fit your need? If so a couple of ways you can get this information:

  • A slot in your model class itself (add Q_OBJECT as well), e.g.
public slots:
    QString roleIndexToString(int index) const
    { /* implement */ }
  • You could also define a new signal in your model class, connect it to the dataChanged signal and do the transformation inside
signals:
    void dataChangedString(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<QString> &roles = QVector<QString> ()))

// in the class constructor
connect(this, &MyClass::dataChanged,
        [](const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles){
            // Fill string vector and emit dataChangedString
});

Upvotes: 1

Related Questions