My question is, that how can I specify a custom object as a role in a model derived from QAbstractListModel
so when visualizing it within a ListView
I can access its member variables. To have an example here is some simple code example:
This is my class representing my custom object:
class MyCustomObject {
public:
MyCustomObject(Qstring name, Qstring type);
QString getName();
QString getType();
private:
QString name;
QString type;
};
This is how the overridden data()
function looks like now (but it is not working) of my MyModel
derived from QAbsractListModel
:
QVariant MyModel::data(const QModelIndex &index, int role) const {
if (index.row() < 0 || index.row() > m_atoms.count()) {
//if (!index.isValid()) {
return QVariant();
}
const MyData &data = m_data[index.row()];
if(role == SomeRole) {
return data.someString()
}
else if (role == MyCustomRole) {
return data.myCustomObject; // How can I do this?
}
return QVariant();
}
Here I specify the role names in MyModel
:
QHash<int, QByteArray> AtomModel::roleNames() const {
QHash<int, QByteArray> roles;
roles[SomeRole] = "someRole";
roles[MyCustomRole] = "myCustomRole";
return roles;
}
and this is how my ListView
looks like in QML code with an example how I would like to access MyCustomObject
member variables in the delegate:
ListView {
width: 400
height: 400
model: myModel
delegate: Text {
text: "Type: " + myCustomRole.getType() + ", Name: " + myCustomRole.getName() + ", some string: " someRole
}
}
EDIT1: => fix needed copy constructor
When I am adding Q_DECLARE_METATYPE under my MyCustomObject
I receive the following error:
call to implicitly-deleted copy constructor of `MyCustomObject`
in instantiation of member function 'QtMetaTypePrivate::QMetaTypeFunctionHelper<MyCustomObject, true>::Construct' requested here
in instantiation of function template specialization 'qRegisterNormalizedMetaType<MyCustomObject>' requested here QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Construct,
return qRegisterNormalizedMetaType<T>(normalizedTypeName, dummy, defined);
in instantiation of function template specialization 'qRegisterMetaType<MyCustomObject>' requested here
Q_DECLARE_METATYPE(MyCustomObject)
expanded from macro 'Q_DECLARE_METATYPE'
#define Q_DECLARE_METATYPE(TYPE) Q_DECLARE_METATYPE_IMPL(TYPE)
expanded from macro 'Q_DECLARE_METATYPE_IMPL'
const int newId = qRegisterMetaType< TYPE >(#TYPE,
copy constructor of 'MyCustomObject' is implicitly deleted because base class 'QObject' has a deleted copy constructor
class MyCustomObject : public QObject
'QObject' has been explicitly marked deleted here Q_DISABLE_COPY(QObject)
expanded from macro 'Q_DISABLE_COPY'
Class(const Class &) Q_DECL_EQ_DELETE;\
EDIT2:
So I have added all the necessary functions what @Evgeny has suggested. My code now compiles without errors, but I get a qml error on run time saying:
TypeError: Property 'getType' of object QVariant(MyCustomObject) is not a function
I have added Q_INVOKABLE
in front of the getType()
method and I also deriving MyCustomObject
class from public QObject
. I have added Q_DECLARE_METATYPE
at the bottom of my MyCustomObject
header file. In the constructor of MyCustomObject
I call qRegisterMetaType<MyCustomObject>("MyCustomObject")
and in my main
I register the class also like this qmlRegisterType<MyCustomObject>("com.test.mycustomobject", 1, 0, "MyCustomObject")
This is how MyCustomObject
class looks like now:
class MyCustomObject : public QObject {
public:
MyCustomObject();
MyCustomObject(Qstring name, Qstring type);
MyCustomObject(const MyCustomObject& obj);
~MyCustomObject();
Q_INVOKABLE QString getName();
Q_INVOKABLE QString getType();
private:
QString name;
QString type;
};
Q_DECLARE_METATYPE(MyCustomObject)
This is how the overridden data()
function looks like now of my MyModel
derived from QAbsractListModel
:
QVariant MyModel::data(const QModelIndex &index, int role) const {
if (index.row() < 0 || index.row() > m_atoms.count()) {
//if (!index.isValid()) {
return QVariant();
}
const MyData &data = m_data[index.row()];
if(role == SomeRole) {
return data.someString()
}
else if (role == MyCustomRole) {
QVariant var; // this is the part, which has changed
var.setValue(data.myCustomObject);
return var;
}
return QVariant();
}
All other functions which I have posted originally are the same.
First of all you need to declare your custom object for Qt metatype system. You should use Q_DECLARE_METATYPE
macro for this. Also you may need to use qRegisterMetaType
function. Then you should register your object to use it with QML. You should use qmlRegisterType
function for that.
Also make sure you use Q_INVOKABLE
for your objects methods.