从C++向QML返回QJSValue时结果始终为undefined的问题
问题原因与解决方案
核心问题出在你创建QJSValue的方式上:你在test()函数里实例了一个局部的QJSEngine,这个引擎对象在函数执行完毕后就会被销毁,它创建的QJSValue也会变成无效对象,所以QML里访问时得到的就是undefined。
QML有自己的全局QJSEngine(也就是你main函数里的QQmlApplicationEngine),你必须用这个引擎来创建QJSValue,才能让QML正常访问。
修改方案一:构造函数传入QML引擎指针
修改MyClass的构造函数,接收QQmlEngine的指针,用它来创建数组:
class MyClass : public QObject { Q_OBJECT Q_PROPERTY(QJSValue test READ test NOTIFY testChanged) public: // 构造函数接收QML引擎指针 explicit MyClass(QJSEngine* engine, QObject *parent = nullptr) : QObject(parent), m_engine(engine) {} QJSValue test() { // 使用传入的QML引擎创建数组 QJSValue l = m_engine->newArray(5); for (int i = 0; i < 5; i++) { l.setProperty(i, i); } return l; } static void RegisterTypes() { qmlRegisterUncreatableType<MyClass>("MyTypes", 1, 0, "MyClass", "Creation of MyClass type not supported"); } Q_SIGNALS: void testChanged(); private: QJSEngine* m_engine; // 保存QML引擎指针 }; int main() { QQmlApplicationEngine engine; // 传入QML引擎的指针 MyClass mc(&engine); MyClass::RegisterTypes(); engine.rootContext()->setContextProperty("myClass", &mc); // ... 加载QML文件等逻辑 }
修改方案二:自动获取当前对象所在的引擎
如果不想手动传指针,可以利用QJSEngine::fromQObject函数,自动获取当前MyClass对象所在的QML引擎:
QJSValue test() { // 获取当前对象绑定的QML引擎 QJSEngine* engine = QJSEngine::fromQObject(this); if (!engine) { // 处理引擎获取失败的情况 return QJSValue(QJSValue::UndefinedValue); } QJSValue l = engine->newArray(5); for (int i = 0; i < 5; i++) { l.setProperty(i, i); } return l; }
这个方案更灵活,不需要修改构造函数,只要MyClass对象被正确设置到QML上下文里,就能拿到对应的引擎。
验证QML访问
修改后,点击按钮就能正常输出数组了:
Button { onClicked: { console.log(myClass.test) // 输出: [0,1,2,3,4] // 也可以直接访问数组元素 console.log(myClass.test[2]) // 输出: 2 } }
内容的提问来源于stack exchange,提问作者DJMcMayhem
相关产品推荐
相关产品推荐

