Unsolved Giving a QList<CustomQ_OBJECTclass> to the QML using setContextProperty
-
Hi !
I have a custom class RoiObject flagged as Q_OBJECT and my QML program has to access to a QList of instances of this type.
So I tried to set the QList as a Q_PROPERTY :Q_PROPERTY(QList<RoiObject> roi_list READ roi_list WRITE roi_list NOTIFY roi_list_changed)
When I run the program, I have the error QMetaProperty::read: Unable to handle unregistered datatype 'QList<RoiObject>' for property RoiModel::roi_list (my getters and setters in RoiModel, the class that instanciates the RoiObjects, are also called roi_list.)
So I tried to store the RoiModel's into a QVariant
Q_PROPERTY(QList<QVariant> roi_list READ roi_list WRITE roi_list NOTIFY roi_list_changed)
but as RoiModel is a QAbstractListModel I need to implement
QVariant RoiModel::data(const QModelIndex &, int) const { const RoiObject& w_roiObject = m_roiList[ai_index.row()]; return w_roiObject.get_attribute(); }
Of course it does not work as i should cast the QVariant to a RoiModel and I can't right ? I tried to use qobject_cast but without surprise it doesn't work.
What can I do to register my RoiModel : public QAbstractListModel class as a contextProperty and make the getter of the QList<RoiObject> callable by the QML pretty please ?|
|
|
|I paste here the RoiModel declaration in case you needs it :
class RoiModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(QList<QVariant> roi_list READ roi_list WRITE roi_list NOTIFY roi_list_changed)//QList<QVariant<RoiObject>> //Q_PROPERTY(QList<RoiModel> roi_list READ roi_list WRITE roi_list NOTIFY roi_list_changed) private: RoiModel(const RoiModel&); const RoiModel& operator=(const RoiModel&); //ATTRIBUTS QQuickView* mp_view; QList<QVariant> m_roiList; protected: public: static enum t_roiRole { ColorRole = Qt::UserRole + 1 , FovHRole = Qt::UserRole + 2 , FovVRole = Qt::UserRole + 3 , AzimuthRole = Qt::UserRole + 4 , ElevationRole = Qt::UserRole + 5 , FactorZoomRole = Qt::UserRole + 6 , RcRole = Qt::UserRole + 7 , FilterRole = Qt::UserRole + 8 , LocalFilterRole = Qt::UserRole + 9 , CompressionRole = Qt::UserRole + 10 , BitrateRole = Qt::UserRole + 11 } mstruct_roles; RoiModel(QQuickView* aip_view, QAbstractListModel* aip_parent = nullptr); void roi_list(QList<RoiObject>); QList<QVariant> roi_list(void) const; int rowCount(const QModelIndex& air_parent = QModelIndex())const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; Q_INVOKABLE void setPosRoi(int ia_id, float ai_azimuth, float ai_elevation); signals: void roi_list_changed(void); public slots: void onRoiChanged(void); };
and data :
QVariant RoiModel::data(const QModelIndex & ai_index, int ai_role) const { if (ai_index.row() < 0 || ai_index.row() >= m_roiList.size()) return QVariant(); const RoiObject* wp_roiObject = &m_roiList[ai_index.row()]; switch (ai_role) { case t_roiRole::ColorRole: return wp_roiObject->color(); //etc...
-
Hi,
Before going down your issue, there's a bigger one to fix. QObject and derived classes are not copyable. You should start by fixing that.
-
@SGaist oh I missed it. Thank you very much.
I edited my post. data is now using a pointer. I think it was the only copy in this code.
[edit]
Ok, I think I did it thanks to your help. The QList<QVariant> doesn't work if I copy the objects and try to use them. However, getting a pointer on a RoiObject from a QVariant seems to work.
BUT the QML still can't access to the attributes set as Q_PROPERTY in RoiObject.onPositionChanged: { cursorPosElOnROI = roiModel.roi_list[ container.idRoi ].elevation;//cannot read property 'elevation' of undefined [...]
Here are the codes relatives to the problem. What can I do to solve it ?
class RoiObject : public QObject { Q_OBJECT Q_PROPERTY(float elevation READ elevation WRITE elevation NOTIFY roiUpdated) //[...] }; Q_DECLARE_METATYPE(QVector<RoiObject>)
class RoiModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(QList<QVariant> roi_list READ roi_list WRITE roi_list NOTIFY roi_list_changed) [...]
QVariant RoiModel::data(const QModelIndex & ai_index, int ai_role) const { if (ai_index.row() < 0 || ai_index.row() >= m_roiList.size()) return QVariant(); const RoiObject* wp_roiObject = m_roiList[ai_index.row()].value<RoiObject*>(); switch (ai_role) { case t_roiRole::ColorRole: return wp_roiObject->color(); [...]