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

QML使用C++ SqlQueryModel 无数据时报lat属性未定义错误

问题现象

在QML项目中使用C++实现的SqlQueryModel操作数据库时,出现以下现象:

  • 数据库表为空时,引用表字段lat报错:qrc:/main.qml:70: ReferenceError: lat is not defined,异常效果如下:
    Faulty behaviour
  • 数据库表存在数据时,字段引用和显示完全正常,效果如下:
    correct behaviour

涉及的核心代码如下:

  1. 字段显示组件
Text {
    id: test1
    anchors.top: test.bottom
    anchors.topMargin: 5
    text: lat
    font.pixelSize: 14
}
  1. 定时器与模型初始化代码
Timer{
    interval: 3000;
    running: true;
    repeat: true;
    onTriggered: {
        sqlModel.insertHistory(22.58369099635166, 113.94935604230989)
    }
}

SqlQueryModel {
    id: sqlModel
    query: "select * from history order by rowid desc"
}
问题原因

报错的核心逻辑是:默认实现的SqlQueryModel仅在查询返回非空结果集时,才会根据返回的列信息注册对应字段的角色名(也就是代码中引用的lat)。当表为空、查询无返回行时,模型不会注册这些字段角色,QML引擎无法找到lat标识符,就会抛出引用错误。当表中插入数据、查询返回结果行后,模型自动注册了对应角色,引用就恢复正常。

解决方案

可以根据实际场景选择以下任意一种方案修复:

方案1:QML端增加空值兜底(改造成本最低)

在引用字段时增加模型行数判断,空表场景下返回默认值,避免直接引用未注册的字段。Qt 5.15及以上版本还可以用可选链+空值合并运算符简化写法:

Text {
    id: test1
    anchors.top: test.bottom
    anchors.topMargin: 5
    // 写法1:兼容所有Qt版本,判断模型行数后再引用字段
    text: sqlModel.rowCount > 0 ? lat : "暂无数据"
    // 写法2:Qt5.15+支持,直接取指定行字段时可以用可选链
    // text: sqlModel.get(0)?.lat ?? "暂无数据"
    font.pixelSize: 14
}

如果是在ListView/Repeater等视图的委托(delegate)中使用字段,可以直接通过视图可见性判断,空表时不加载委托、显示占位提示:

ListView {
    anchors.fill: parent
    model: sqlModel
    // 有数据时才显示列表、加载委托
    visible: sqlModel.rowCount > 0
    delegate: Text {
        text: lat
        font.pixelSize: 14
    }
}

// 空表占位提示
Text {
    anchors.centerIn: parent
    text: "暂无历史数据"
    visible: sqlModel.rowCount === 0
}

方案2:C++端固定注册字段角色(最彻底的修复)

修改自定义SqlQueryModel子类的roleNames重写实现,无论查询结果是否为空,都固定返回所有表字段对应的角色,从根源上避免空表时角色丢失的问题:

QHash<int, QByteArray> SqlQueryModel::roleNames() const {
    QHash<int, QByteArray> roles;
    // 固定注册所有字段角色,不要依赖查询结果动态生成
    roles[Qt::UserRole + 1] = "lat";
    roles[Qt::UserRole + 2] = "lng";
    // 其余表字段按查询顺序补充即可
    return roles;
}

如果模型需要支持动态查询不同的表,可以在执行setQuery时提前读取查询的字段元信息,预先生成角色列表,不要等有返回数据时才生成角色。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 11:18:36