为什么我在使用 C++ QAbstractListModel 时需要 `text: model.display.foo` 而不仅仅是 `text: foo`?

Why do I need `text: model.display.foo` instead of just `text: foo` when using a C++ QAbstractListModel?

非常 Qt / QtQuick 新手。

我用 Qt Designer 设计了 ​​a simple form,它由 ListView.

组成
Item {
    // ... 
    ListView {
        id: listView1
        anchors.fill: parent
        model: FooModel
        delegate: Item {
            // ... 
            Row {
                id: row1
                Text {
                    text: foo
                    // ... 
                }
            }
        }
    }
}

这在以下情况下工作得很好 - 通过将其内联复制粘贴为 model,或者让 qmlscene 或 Qt Designer 注意到 [=19] 中包含的 FooModel.qml =]:

ListModel {
    ListElement {
        foo: "1"
    }

    ListElement {
        foo: "2"
    }

    ListElement {
        foo: "3"
    }

    ListElement {
        foo: "4"
    }
}

但是,当我尝试用子类 QAbstractListModelan actual C++ model 替换我的虚拟模型时,我必须将 text: foo 替换为 text: model.display.foodelegate:

delegate: Item {
        // ... 
        Row {
            id: row1
            Text {
                text: model.display.foo // <=== See? 
                // ... 
            }
        }
    }

如果我不这样做,Qt 会抱怨

qrc:/MainForm.ui.qml:23: ReferenceError: foo is not defined

没有任何显示。

我这样设置模型属性,in my main.cpp:

FooListModel* flm= new FooListModel();
QQmlContext *ctxt = engine.rootContext();
ctxt->setContextProperty("FooModel", flm);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();

这是为什么?

此外 - 假设 "it's a feature and not a bug" - 必须更改 text 属性意味着我不能再在 QtDesigner 中拥有我的虚拟数据或使用内联模型进行原型制作; 我能以任何方式避免这种情况吗?


请找到有问题的 MWE here on Github

qrc:/MainForm.ui.qml:23: ReferenceError: foo is not defined

意味着你必须在FooListModel中定义foo角色。例如,

class FooListModel : public QAbstractListModel
{
public:
    enum FooListModelRoles 
    {
        FooRole = Qt::UserRole + 1,
        BarRole, 
        //...
    }

    QHash<int, QByteArray> roleNames() const //override
    {
        QHash<int, QByteArray> roleName;
        roleName[FooRole] = "foo";  //define "foo" role for QML
        roleName[BarRole] = "bar";  //define "bar" role for QML
        return roleName;
    }

    //...
}

QML 中的委托现在可以访问 foo 角色。

Also - assuming "it's a feature and not a bug"

是的,text: model.display.foo 工作正常,因为 displayQAbstractItemModel 中的预定义角色。