You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QML调用注册为不可创建类型的C++类函数时触发TypeError

问题原因及解决方法

核心原因

  • 混淆了类型注册和实例传递的作用:qmlRegisterUncreatableType仅用于让QML识别gui::Wallet这个类型(比如支持类型注解、信号槽关联等),但不会自动把类的实例注入到QML上下文。之前用setContextProperty是直接传递了可调用的实例,现在只注册类型的话,QML中直接调用Wallet.getSyncPercentage()本质是在调用静态方法,而你的函数是实例方法,自然报错。
  • QML调用方式错误:如果没有在上下文里注入实例,直接用类型名调用实例方法,会被QML判定为类型不匹配,触发TypeError。

解决方法

1. 结合setContextProperty传递实例

注册类型后,仍需把gui::Wallet的实例通过上下文传递给QML,两者缺一不可:

// 先注册类型
qmlRegisterUncreatableType<gui::Wallet>("com.yourdomain.wallet", 1, 0, "Wallet", "Cannot create Wallet instances in QML");

// 再传递实例到QML上下文
gui::Wallet walletInstance;
engine.rootContext()->setContextProperty("wallet", &walletInstance);

之后在QML中通过注入的实例调用方法:

import com.yourdomain.wallet 1.0

// 调用实例方法
Text { text: wallet.getSyncPercentage().toString() }

2. 检查Q_INVOKABLE的声明位置

确保getSyncPercentage()在gui::Wallet类的public区域用Q_INVOKABLE标记,否则QML无法访问该方法:

class Wallet : public QObject
{
    Q_OBJECT
public:
    // 必须放在public下,且标记Q_INVOKABLE
    Q_INVOKABLE double getSyncPercentage() {
        // 实现逻辑
        return syncPercent;
    }
};

3. 验证类型注册的参数匹配

检查注册时的命名空间、版本号,和QML中的导入语句完全一致:

  • C++注册代码的命名空间是com.yourdomain.wallet、版本1.0,QML中必须对应写import com.yourdomain.wallet 1.0
  • 注册时的类型名(第三个参数"Wallet")要和QML中引用的类型名一致

内容的提问来源于stack exchange,提问作者user20040030

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 21:40:21