There's a model (currently it's derived from QAbstractItemModel
, but it can also be any model that provides named data roles) from which I need to get data, knowing a row/column and a role name. I can get index by row and column:
const index = mYModel.index(row, column);
I can also get data by index and role:
const data = myModel.data(index, role);
I haven't found any way to somehow find out the role by its name. Am I missing something or is this impossible at all?
Here's the pseudocode:
// MyModel.h
class MyModel: public QAbstractItemModel
{
public:
QHash<int, QByteArray> roleNames() const override
{
QHash<int, QByteArray> roleNames;
roleNames[Qt::UserRole 1] = "someRole";
return roleNames;
}
};
// Item.qml
Item {
ListView {
model: myModel
delegate: myDelegate
}
Button {
onClicked: {
const rowIndex = Math.random(myModel.count);
// here I need to get data for item at
// row rowIndex, column 0 and role name "someRole"
}
}
}
CodePudding user response:
Since your model is used in a ListView, I would use the itemAtIndex
function of that ListView:
ListView {
id: theList
model: myModel
delegate: UnknownItem {
property var theModel: model //have to add this property
}
}
Button {
onClicked: {
let item = theList.itemAtIndex(theList.currentIndex)
if(item) {
console.log("clicked", item.theModel.title)
}
}
}
Note that this works with integer index, not on the QModelIndex you have in your question.
CodePudding user response:
I don't see any built-in features to do that. So the easiest solution for me is to create a helper class that will retrieve the necessary data from the given model.
Helper class:
class ModelHelper : public QObject
{
Q_OBJECT
Q_PROPERTY(QVariant model READ model WRITE setModel)
public:
explicit ModelHelper(QObject *parent = nullptr)
: QObject(parent)
{}
QVariant model() const
{
return m_model;
}
void setModel(const QVariant &model)
{
m_model = model;
}
Q_INVOKABLE QVariant data(int row, const QString &roleName) const
{
if (const QAbstractItemModel *model = m_model.value<QAbstractItemModel*>()) {
const QHash<int, QByteArray> roleNames = model->roleNames();
for (auto i = roleNames.cbegin(); i != roleNames.cend(); i) {
if (i.value() == roleName) {
return model->data(model->index(row, 0), i.key());
}
}
}
return QVariant();
}
private:
QVariant m_model;
};
//...
qmlRegisterType<ModelHelper>("Test.ModelUtils", 1, 0, "ModelHelper");
How to use:qml
import Test.ModelUtils 1.0
//...
ListModel {
id: listModel
ListElement { name: "John" }
ListElement { name: "Mike" }
}
ModelHelper {
id: modelHelper
model: listModel
}
Button {
text: "Print Data"
onClicked: {
const data = [];
for (let i = 0; i < listModel.count; i) {
data.push(modelHelper.data(i, "name"));
}
console.log(data);
}
}