Cannot add model to QML
-
Hello, I cannot add C++ model to QML which runs in QQuickWidget. I get error while running the application. Error is : "qrc:/Gauge.qml:43: ReferenceError: DataModel is not defined". I can see the gauge when the program is run, it is only that the value is not updating the gauge.
My code is like this:
//main.cpp int main(int argc, char *argv[]) { QApplication app(argc, argv); QQmlApplicationEngine* engine = new QQmlApplicationEngine(); DataModel datamodel; engine->rootContext()->setContextProperty("DataModel", &datamodel); engine->load(QUrl(QStringLiteral("qrc:/Gauge.qml"))); if (engine->rootObjects().isEmpty()) return -1; MainWindow w; w.show(); return app.exec();
//mainwindow.cpp MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); ui->quickWidget->setSource(QUrl(QStringLiteral("qrc:/Gauge.qml"))); } MainWindow::~MainWindow() { delete ui; }
//datamodel.cpp #include "datamodel.h" #include <iostream> #include <QTimer> int temp = 0; DataModel::DataModel(QObject *parent) : QObject (parent) { m_num = 10; qDebug() << "Creating datamodel constructing..."; m_timer = new QTimer(this); connect(m_timer, SIGNAL(timeout()), this, SLOT(update())); m_timer->start(1000); } int DataModel::num() const { return m_num; } void DataModel::update() { temp += 5; this->setNum(temp); qDebug() << "Updating value:" << m_num; } void DataModel::setNum(int num) { if (m_num == num) return; qDebug() << "Setting value:" << num; m_num = num; emit numChanged(m_num); }
// datamodel.h #ifndef DATAMODEL_H #define DATAMODEL_H #include <QObject> #include <QTimer> #include <QDebug> class DataModel : public QObject { Q_OBJECT Q_PROPERTY(int num READ num WRITE setNum NOTIFY numChanged) public: explicit DataModel(QObject *parent = nullptr); int num() const; signals: void numChanged(int num); void operate(); public slots: void setNum(int num); void update(); private: int m_num; QTimer* m_timer; }; #endif // DATAMODEL_H
//Gauge.qml CircularGauge { value: DataModel.num anchors.centerIn: parent } }
-
Your MainWindow is creating another QML engine which does not have "DataModel" set.
-
@milan said in Cannot add model to QML:
QQmlApplicationEngine* engine = new QQmlApplicationEngine();
remove the engine since you're not using it anywhere. Or remove MainWindow if you are not using that. I don't know which is true in your case.
Extract the engine from your
ui->quickWidget
and add the DataModel there. If you are using QQuickWidget, you can use https://doc.qt.io/qt-5/qquickwidget.html#engine. -
@milan said in Cannot add model to QML:
qDebug() << "Setting value:" << num;
Do you see this message printed?
-
@milan said in Cannot add model to QML:
@sierdzio . I see that DataModel object gets destructed after it is constructed.
So make sure it lives long :-)
-
@milan said in Cannot add model to QML:
@sierdzio. Yes I did that. Is qmlregistertype better way that setContextProperty I am using now? The C++ model should update the qml
No it is not better, it server a different purpose. It makes the type recognizable (and creatable) in QML. Since you want to use a global data model (I think), then setting the context property is a better way for your use case. Just make sure DataModel object is not destroyed while your UI is alive. You can do it, for example, by declaring it as a member variable of MainWindow class, or by creating an object on heap and assigning MainWindow as parent.