Qt: ОШИБКА в представлении класса C++ в QML
Я продолжаю получать ту же ошибку при запуске приложения:
qrc: /main.qml: 13: ReferenceError: _myClass не определен
Где ошибка?
Кроме того, если я хочу подключить сигнал myIntChanged к слоту, где я должен разместить свое соединение? В main.cpp или в конструкторе MyClass?
myclass.h
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QObject>
#include <QString>
#include <QDebug>
#include <QTimer>
class MyClass : public QObject
{
Q_OBJECT
public:
MyClass(QObject *parent = 0);
Q_PROPERTY(int myInt READ getMyInt WRITE setMyInt NOTIFY myIntChanged)
int myInt;
inline int getMyInt() { return myInt; }
inline void setMyInt(int _value) { myInt = _value; }
private:
void initVariables();
QTimer *timer;
private slots:
void editVariables();
signals:
void myIntChanged();
};
#endif // MYCLASS_H
myclass.cpp
#include "myclass.h"
MyClass::MyClass(QObject *parent) : QObject (parent)
{
initVariables();
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(editVariables()));
timer -> start(3000);
}
void MyClass::initVariables()
{
myInt = 0;
}
void MyClass::editVariables()
{
myInt = myInt + 1;
qDebug() << "myclass.cpp: timeout: variables edited.";
}
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "myclass.h"
int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
MyClass *myClass = new MyClass();
engine.rootContext() -> setContextProperty("_myClass", myClass);
return app.exec();
}
main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Exposed C++ Class")
Text {
anchors.top: parent.top; anchors.topMargin: 30
anchors.left: parent.left; anchors.leftMargin: 30
text: _myClass.myInt
}
}
1 ответ
Проблема вызвана тем, что с load()
оператор, загружающий файл.qml, при чтении и проверке существования переменных понимает, что этот объект не существует, так как он передается им через setContextProperty()
Возможное решение - передать объект перед загрузкой.qml:
int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
MyClass *myClass = new MyClass();
engine.rootContext()->setContextProperty("_myClass", myClass);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
Он не обновляется, потому что он не был уведомлен через сигналы, которые вы объявили, правильная вещь, которую нужно сделать, это излучать сигнал каждый раз, когда свойство изменяется, вы должны изменить некоторые методы:
inline void setMyInt(int _value) {
if(myInt == _value)
return;
myInt = _value;
emit myIntChanged();
}
void MyClass::editVariables()
{
setMyInt(getMyInt()+1);
qDebug() << "myclass.cpp: timeout: variables edited.";
}