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

QAbstractListModel::Data()未被调用,QML无法显示C++模型数据

问题排查与解决

你的QML看不到数据的核心原因是两个关键的实现错误,导致QML无法正确和C++模型交互:

1. 角色名方法拼写错误,QML无法识别数据角色

你在UserListModel里写的是rolesNames()(多了一个s),但Qt的QAbstractItemModel要求的虚函数是**roleNames()**(少一个s)!这个拼写错误直接导致QML无法获取你定义的macRole对应的"mac"角色名,自然不会触发data()方法去拿数据。

修复方法:把方法名改成正确的roleNames(),并且加上override关键字确保正确重写父类方法:

QHash<int, QByteArray> roleNames() const override {
    QHash<int, QByteArray> roles;
    roles[macRole] = "mac";
    return roles;
}

2. index()和parent()方法实现完全错误

QAbstractListModel是一维列表模型,这两个方法的实现规则很明确:

  • parent():列表里的每一项都没有父节点,所以必须返回空的QModelIndex
  • index():需要调用createIndex()生成对应行的有效索引,而不是直接返回入参

你原来的实现会让QML无法正确遍历模型结构,根本找不到要显示的列表项,所以data()和roleNames()都不会被调用。

修复这两个方法:

QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override {
    // 列表模型只有一列,且父节点必须为空
    if (!hasIndex(row, column, parent))
        return QModelIndex();
    return createIndex(row, column, nullptr);
}

QModelIndex parent(const QModelIndex &index) const override {
    // 列表项无父节点,返回空索引
    Q_UNUSED(index);
    return QModelIndex();
}

额外优化建议

  • 你的User类如果要支持属性通知(比如后续修改mac地址自动更新UI),需要继承QObject并添加Q_PROPERTY,同时setMacAddr的参数建议用const QString&避免不必要的拷贝:
    class User : public QObject {
        Q_OBJECT
        Q_PROPERTY(QString macAddr READ macAddr WRITE setMacAddr NOTIFY macAddrChanged)
    private:
        QString m_macAddr;
    public:
        explicit User(QObject *parent = nullptr) : QObject(parent) {}
        User(const QString &mac, QObject *parent = nullptr) : QObject(parent), m_macAddr(mac) {}
        QString macAddr() const { return m_macAddr; }
        void setMacAddr(const QString &mac) {
            if (mac == m_macAddr) return;
            m_macAddr = mac;
            emit macAddrChanged();
        }
    signals:
        void macAddrChanged();
    };
    
  • 你自定义的getIndex()方法其实是多余的,QAbstractListModel原生的index()方法修复后就能正常生成索引,不需要额外定义。

为什么main函数里调用data()能拿到数据?

因为你在main里是通过getIndex()直接调用createIndex()生成了有效索引,绕开了你错误实现的index()方法,所以能正常获取数据,但QML是通过模型的标准接口去访问的,自然就失败了。

修复完上面两个核心问题后,你的QML ListView应该就能正常显示每个项的mac地址了。

内容的提问来源于stack exchange,提问作者Samir N Ahmad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 06:31:38