QAbstractListModel items cannot inherit from QObject
-
Hello,
I have a QAbstractListModel that should have items that inherit from QObject(named gaugeobject)
When the Item does not inherit from QObject it's working, but when inherited I get a error:
use of deleted function 'GaugeObject::GaugeObject(const GaugeObject&)' if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) n->v = new T(t); ^If I understand it right, there is something wrong witht the default constructor?
This is the class:#ifndef GAUGEOBJECT_H #define GAUGEOBJECT_H #include <QObject> #include <QVariantMap> class GaugeObject : public QObject { public: GaugeObject(const int &id, const QString &mainValue, const QString &secValue, const int &width, const int &height, const int &x, const int &y, const int &size); GaugeObject(QObject *parent = nullptr); .....#include "gaugeobject.h" GaugeObject::GaugeObject(QObject *parent) : QObject (parent) { } GaugeObject::GaugeObject(const int &id, const QString &mainValue, const QString &secValue, const int &width, const int &height, const int &x, const int &y, const int &size): m_id(id), m_mainValue(mainValue), m_secValue(secValue), m_width(width), m_height(height), m_x(x), m_y(y), m_size(size) { } ...... -
No such issue. It works.
You cannot copy the object of QObject types. Can you show how are you creating the list inside the QAbstractListModel ? -
model header:
#ifndef GaugeModel_H #define GaugeModel_H #include "gaugeobject.h" #include <QAbstractListModel> class GaugeModel : public QAbstractListModel { Q_OBJECT public: enum gaugeRoles { idRole = Qt::UserRole, }; explicit GaugeModel(QObject *parent = nullptr); Q_INVOKABLE void addGaugeObject(const GaugeObject &GaugeObject); Q_INVOKABLE QVariantMap get(int row) const; int rowCount(const QModelIndex &parent = QModelIndex()) const override; Q_INVOKABLE QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; Qt::ItemFlags flags(const QModelIndex& index) const override; QHash<int, QByteArray> roleNames() const override; private: QList<GaugeObject> m_GaugeObjects; }; #endif // GaugeModel_HCpp:
#include "GaugeModel.h" GaugeModel::GaugeModel(QObject *parent) : QAbstractListModel(parent) { } QVariantMap GaugeModel::get(int row) const { return m_GaugeObjects[row].toMap(); } void GaugeModel::addGaugeObject(const GaugeObject &GaugeObject) { beginInsertRows(QModelIndex(), rowCount(), rowCount()); m_GaugeObjects << GaugeObject; endInsertRows(); } int GaugeModel::rowCount(const QModelIndex &parent) const { if(parent.isValid()) return 0; return m_GaugeObjects.count(); } QVariant GaugeModel::data(const QModelIndex &index, int role) const { if(index.row() < 0 || index.row() >= m_GaugeObjects.count() || !index.isValid()) return QVariant(); const GaugeObject &gaugeObject = m_GaugeObjects[index.row()]; if ( role == idRole) return gaugeObject.id(); return QVariant(); } bool GaugeModel::setData(const QModelIndex &index, const QVariant &value, int role) { GaugeObject &gaugeObject = m_GaugeObjects[index.row()]; if(data(index, role) != value) { if(role == idRole) gaugeObject.setId(value.toInt()); emit dataChanged(index, index, QVector<int>() << role); return true; } return false; } Qt::ItemFlags GaugeModel::flags(const QModelIndex &index) const { if(!index.isValid()) return Qt::NoItemFlags; return Qt::ItemIsEditable; } QHash<int, QByteArray> GaugeModel::roleNames() const { QHash<int, QByteArray> roles; roles[idRole] = "id"; return roles; } -
model header:
#ifndef GaugeModel_H #define GaugeModel_H #include "gaugeobject.h" #include <QAbstractListModel> class GaugeModel : public QAbstractListModel { Q_OBJECT public: enum gaugeRoles { idRole = Qt::UserRole, }; explicit GaugeModel(QObject *parent = nullptr); Q_INVOKABLE void addGaugeObject(const GaugeObject &GaugeObject); Q_INVOKABLE QVariantMap get(int row) const; int rowCount(const QModelIndex &parent = QModelIndex()) const override; Q_INVOKABLE QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; Qt::ItemFlags flags(const QModelIndex& index) const override; QHash<int, QByteArray> roleNames() const override; private: QList<GaugeObject> m_GaugeObjects; }; #endif // GaugeModel_HCpp:
#include "GaugeModel.h" GaugeModel::GaugeModel(QObject *parent) : QAbstractListModel(parent) { } QVariantMap GaugeModel::get(int row) const { return m_GaugeObjects[row].toMap(); } void GaugeModel::addGaugeObject(const GaugeObject &GaugeObject) { beginInsertRows(QModelIndex(), rowCount(), rowCount()); m_GaugeObjects << GaugeObject; endInsertRows(); } int GaugeModel::rowCount(const QModelIndex &parent) const { if(parent.isValid()) return 0; return m_GaugeObjects.count(); } QVariant GaugeModel::data(const QModelIndex &index, int role) const { if(index.row() < 0 || index.row() >= m_GaugeObjects.count() || !index.isValid()) return QVariant(); const GaugeObject &gaugeObject = m_GaugeObjects[index.row()]; if ( role == idRole) return gaugeObject.id(); return QVariant(); } bool GaugeModel::setData(const QModelIndex &index, const QVariant &value, int role) { GaugeObject &gaugeObject = m_GaugeObjects[index.row()]; if(data(index, role) != value) { if(role == idRole) gaugeObject.setId(value.toInt()); emit dataChanged(index, index, QVector<int>() << role); return true; } return false; } Qt::ItemFlags GaugeModel::flags(const QModelIndex &index) const { if(!index.isValid()) return Qt::NoItemFlags; return Qt::ItemIsEditable; } QHash<int, QByteArray> GaugeModel::roleNames() const { QHash<int, QByteArray> roles; roles[idRole] = "id"; return roles; } -
@jsulm said in QAbstractListModel items cannot inherit from QObject:
@Slash200 See http://doc.qt.io/qt-5/qobject.html#no-copy-constructor-or-assignment-operator
Ok so it's normal that I used a class not inherited from QObject for models.
Thank you.But that brings me to a problem. I want to add objects to that model from QML, but I cant access the class from QML when it's not inherited from QObject.
-
You can pass the parameters from QML to C++ side and construct object c++ itself.
-
model header:
#ifndef GaugeModel_H #define GaugeModel_H #include "gaugeobject.h" #include <QAbstractListModel> class GaugeModel : public QAbstractListModel { Q_OBJECT public: enum gaugeRoles { idRole = Qt::UserRole, }; explicit GaugeModel(QObject *parent = nullptr); Q_INVOKABLE void addGaugeObject(const GaugeObject &GaugeObject); Q_INVOKABLE QVariantMap get(int row) const; int rowCount(const QModelIndex &parent = QModelIndex()) const override; Q_INVOKABLE QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; Qt::ItemFlags flags(const QModelIndex& index) const override; QHash<int, QByteArray> roleNames() const override; private: QList<GaugeObject> m_GaugeObjects; }; #endif // GaugeModel_HCpp:
#include "GaugeModel.h" GaugeModel::GaugeModel(QObject *parent) : QAbstractListModel(parent) { } QVariantMap GaugeModel::get(int row) const { return m_GaugeObjects[row].toMap(); } void GaugeModel::addGaugeObject(const GaugeObject &GaugeObject) { beginInsertRows(QModelIndex(), rowCount(), rowCount()); m_GaugeObjects << GaugeObject; endInsertRows(); } int GaugeModel::rowCount(const QModelIndex &parent) const { if(parent.isValid()) return 0; return m_GaugeObjects.count(); } QVariant GaugeModel::data(const QModelIndex &index, int role) const { if(index.row() < 0 || index.row() >= m_GaugeObjects.count() || !index.isValid()) return QVariant(); const GaugeObject &gaugeObject = m_GaugeObjects[index.row()]; if ( role == idRole) return gaugeObject.id(); return QVariant(); } bool GaugeModel::setData(const QModelIndex &index, const QVariant &value, int role) { GaugeObject &gaugeObject = m_GaugeObjects[index.row()]; if(data(index, role) != value) { if(role == idRole) gaugeObject.setId(value.toInt()); emit dataChanged(index, index, QVector<int>() << role); return true; } return false; } Qt::ItemFlags GaugeModel::flags(const QModelIndex &index) const { if(!index.isValid()) return Qt::NoItemFlags; return Qt::ItemIsEditable; } QHash<int, QByteArray> GaugeModel::roleNames() const { QHash<int, QByteArray> roles; roles[idRole] = "id"; return roles; }Store the pointers to your GaugeObjects in your model as described from the link of @jsulm
The main consequence is that you should use pointers to QObject (or to your QObject subclass) where you might otherwise be tempted to use your QObject subclass as a value. For example, without a copy constructor, you can't use a subclass of QObject as the value to be stored in one of the container classes. You must store pointers.
QList<GaugeObject *> m_GaugeObjects;