QML doesn't "see" my subclass of QAbstructListModel
-
Hello,
following this post, I've created a subclass ofQAbstructListItem
and now I'm trying to make QML interact with it by passing it to as a context property.I can successfully pass a pointer to qml, (As in I can print the address I passed as text), but the QML ListView doesn't seem to recognize it as a valid model.)
I tried to put a breakpoint on some of the model methods such as
rowCount
anddata
and it seems they are never called.I also tried registering the model with
qRegisterMetaType
which had no effectindicatorlistmodel.h
class IndicatorListModel: public QAbstractListModel { Q_OBJECT public: explicit IndicatorListModel(QObject* parent = nullptr); IndicatorListModel(const IndicatorListModel& other); ~IndicatorListModel(); // QAbstractItemModel interface int rowCount(const QModelIndex& parent) const; QVariant data(const QModelIndex& index, int role) const; QHash<int, QByteArray> roleNames() const; void SetModelData(QList<IndicatorBase*> dataList); private: QList<IndicatorBase*> _indicatorDataList; };
In my main file, I generate some data for this class like this:
main.cpp
IndicatorListModel listModel; QList<IndicatorBase *> indicatorList; indicatorList.append(new LedSingleIndicator(true,"RAM 1")); indicatorList.append(new LedSingleIndicator(true,"RAM 2")); indicatorList.append(new LedSingleIndicator(true,"RAM 3")); listModel.SetModelData(indicatorList); qDebug() << "Model size: " << listModel.rowCount(QModelIndex()); //prints out "Model size: 3"
I then pass the model to qml as a context property like this:
QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); QQmlContext* context = engine.rootContext(); context->setContextProperty("model",&listModel); engine.load(url); return app.exec();
In my main QML there is a simple ListView:
Window { id:mainwindow width: 640 height: 480 visible: true title: qsTr("Hello World") Component.onCompleted: { console.debug("Component Main Window loaded.."); } color:"green" Text{ anchors.centerIn: parent text: "Model is: " + model //prints `Model is: IndicatorListModel(0xa8fc70)` } ListView{ id: listView width: 400 height: 400 model: model delegate: Text{ text: "Sample Text" } } // ListView{ // id: listview // anchors.fill: parent // required model // delegate: Text{ // required property string labelRole // text: "Indicator Name: " + labelRole // } // } }
QML Window looks like this:
I can't figure out why the ListView doesn't recognize my model as a proper model. Any help would be appreciated.
-
OK, so apparently the name
model
is the cause of my problem.Doesn't Work:
context->setContextProperty("model",&listModel);
Works:
context->setContextProperty("myModel",&listModel);
-
Hello,
following this post, I've created a subclass ofQAbstructListItem
and now I'm trying to make QML interact with it by passing it to as a context property.I can successfully pass a pointer to qml, (As in I can print the address I passed as text), but the QML ListView doesn't seem to recognize it as a valid model.)
I tried to put a breakpoint on some of the model methods such as
rowCount
anddata
and it seems they are never called.I also tried registering the model with
qRegisterMetaType
which had no effectindicatorlistmodel.h
class IndicatorListModel: public QAbstractListModel { Q_OBJECT public: explicit IndicatorListModel(QObject* parent = nullptr); IndicatorListModel(const IndicatorListModel& other); ~IndicatorListModel(); // QAbstractItemModel interface int rowCount(const QModelIndex& parent) const; QVariant data(const QModelIndex& index, int role) const; QHash<int, QByteArray> roleNames() const; void SetModelData(QList<IndicatorBase*> dataList); private: QList<IndicatorBase*> _indicatorDataList; };
In my main file, I generate some data for this class like this:
main.cpp
IndicatorListModel listModel; QList<IndicatorBase *> indicatorList; indicatorList.append(new LedSingleIndicator(true,"RAM 1")); indicatorList.append(new LedSingleIndicator(true,"RAM 2")); indicatorList.append(new LedSingleIndicator(true,"RAM 3")); listModel.SetModelData(indicatorList); qDebug() << "Model size: " << listModel.rowCount(QModelIndex()); //prints out "Model size: 3"
I then pass the model to qml as a context property like this:
QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); QQmlContext* context = engine.rootContext(); context->setContextProperty("model",&listModel); engine.load(url); return app.exec();
In my main QML there is a simple ListView:
Window { id:mainwindow width: 640 height: 480 visible: true title: qsTr("Hello World") Component.onCompleted: { console.debug("Component Main Window loaded.."); } color:"green" Text{ anchors.centerIn: parent text: "Model is: " + model //prints `Model is: IndicatorListModel(0xa8fc70)` } ListView{ id: listView width: 400 height: 400 model: model delegate: Text{ text: "Sample Text" } } // ListView{ // id: listview // anchors.fill: parent // required model // delegate: Text{ // required property string labelRole // text: "Indicator Name: " + labelRole // } // } }
QML Window looks like this:
I can't figure out why the ListView doesn't recognize my model as a proper model. Any help would be appreciated.
@Curtwagner1984 additionally to the really unfortunate naming you choose, please move your function to the correct section of your class and mark them as override so that you're sure, that you are actually overriding the correct functions:
public: int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; protected: QHash<int, QByteArray> roleNames() const override;
-
@Curtwagner1984 additionally to the really unfortunate naming you choose, please move your function to the correct section of your class and mark them as override so that you're sure, that you are actually overriding the correct functions:
public: int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; protected: QHash<int, QByteArray> roleNames() const override;
@J-Hilk
Will do, Thank you!