从 QML 访问属性 C++ 对象
Access an attribute c++ object from QML
我在理解如何使用 qml 中的 C++ 单例对象时遇到问题。
我知道我必须从 QObject class 继承我的 classes 并且我必须公开属性。
为了让它们在 qml 中可用,我必须执行 setContextProperty("ClassName", &class name).
但是,如果我们承认这个 class 包含另一个对象并且我希望能够从 qml 中使用它,我会从未定义的对象中收到类似“无法调用方法名称”的错误。
示例:
APi.h
class API : public QObject {
Q_OBJECT
Q_PROPERTY(User *user READ getUser WRITE setUser NOTIFY userChanged)
public:
Q_INVOKABLE inline User *getUser() const {
qDebug() << "get called";
return user;
};
inline void setUser(User *new_user) { this->user = new_user; };
signals:
void userChanged();
private:
User *user;
};
User.h
#ifndef USER_H
#define USER_H
#include <QObject>
#include <QString>
class User: public QObject{
Q_OBJECT
public:
Q_INVOKABLE inline QString &getName(){return name;}; // qrc:/main.qml:63: TypeError: Cannot call method 'getName' of undefined
private:
QString name;
};
#endif // USER_H
main.cpp
#include <QQmlContext>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQuick3D/qquick3d.h>
#include "API.h"
#include "User.h"
int main(int argc, char *argv[]) {
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
API api;
User user;
api.setUser(&user);
engine.rootContext()->setContextProperty("API", &api);
qmlRegisterType<User>("User", 1, 0, "User");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
main.qml
import QtQuick
import QtQuick3D
import QtQuick.Controls
import QtQuick.Layouts
Window {
Item{
id: test
Component.onCompleted: {
console.log("Completed")
API.getUser() // no error, getUser is called without error
console.log(API.getUser().getName())
}
}
}
我有什么可能通过API从qml访问用户对象?
您可以执行以下任一操作:
在API中添加一个public插槽 class:
API.cpp:
QString API::getUserName()
{
return user.getName();
}
main.qml:
Component.onCompleted: console.log( API.getUserName() )
将用户设为 Q_PROPERTY API class:
API.h:
Q_PROPERTY( User* user READ user NOTIFY userChanged)
main.qml:
Component.onCompleted: console.log( API.user.getName() )
使用 QML 注册用户:
main.cpp:
qmlRegisterType<User>("MyUser", 1, 0, "MyUser");
main.qml:
Component.onCompleted: console.log( API.getUser().getName() )
我在理解如何使用 qml 中的 C++ 单例对象时遇到问题。 我知道我必须从 QObject class 继承我的 classes 并且我必须公开属性。 为了让它们在 qml 中可用,我必须执行 setContextProperty("ClassName", &class name).
但是,如果我们承认这个 class 包含另一个对象并且我希望能够从 qml 中使用它,我会从未定义的对象中收到类似“无法调用方法名称”的错误。
示例:
APi.h
class API : public QObject {
Q_OBJECT
Q_PROPERTY(User *user READ getUser WRITE setUser NOTIFY userChanged)
public:
Q_INVOKABLE inline User *getUser() const {
qDebug() << "get called";
return user;
};
inline void setUser(User *new_user) { this->user = new_user; };
signals:
void userChanged();
private:
User *user;
};
User.h
#ifndef USER_H
#define USER_H
#include <QObject>
#include <QString>
class User: public QObject{
Q_OBJECT
public:
Q_INVOKABLE inline QString &getName(){return name;}; // qrc:/main.qml:63: TypeError: Cannot call method 'getName' of undefined
private:
QString name;
};
#endif // USER_H
main.cpp
#include <QQmlContext>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtQuick3D/qquick3d.h>
#include "API.h"
#include "User.h"
int main(int argc, char *argv[]) {
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
API api;
User user;
api.setUser(&user);
engine.rootContext()->setContextProperty("API", &api);
qmlRegisterType<User>("User", 1, 0, "User");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
main.qml
import QtQuick
import QtQuick3D
import QtQuick.Controls
import QtQuick.Layouts
Window {
Item{
id: test
Component.onCompleted: {
console.log("Completed")
API.getUser() // no error, getUser is called without error
console.log(API.getUser().getName())
}
}
}
我有什么可能通过API从qml访问用户对象?
您可以执行以下任一操作:
在API中添加一个public插槽 class:
API.cpp:
QString API::getUserName()
{
return user.getName();
}
main.qml:
Component.onCompleted: console.log( API.getUserName() )
将用户设为 Q_PROPERTY API class:
API.h:
Q_PROPERTY( User* user READ user NOTIFY userChanged)
main.qml:
Component.onCompleted: console.log( API.user.getName() )
使用 QML 注册用户:
main.cpp:
qmlRegisterType<User>("MyUser", 1, 0, "MyUser");
main.qml:
Component.onCompleted: console.log( API.getUser().getName() )