无法在QML ListView中调用Qt C ++方法

时间:2019-01-10 07:19:29

标签: c++ qt qml

我有一个QObjects列表,用作ListView的qml模型。我可以更改其属性,但不能调用任何插槽或Q_INVOKABLE方法。这是我的问题的最小示例(可惜它仍然很大)。

使用属性和可调用方法定义一个非常简单的类


    // DummyObject.h

    class DummyElem : public QObject
    {
        Q_OBJECT

        Q_PROPERTY(QString dummy READ getDummy CONSTANT)
    public:
        explicit DummyElem(QObject *parent = nullptr);

        QString getDummy();
        Q_INVOKABLE void notifyStuff();
    };
实现这个简单类的简单方法
    // DummyObject.cpp

    #include "DummyElem.h"
    #include <QDebug>

    DummyElem::DummyElem(QObject *parent) : QObject(parent) {}

    QString DummyElem::getDummy() {return "lorem";}
    void DummyElem::notifyStuff() {qDebug() << "ipsum";}
使用列表作为根属性启动qml应用程序。完全是从教程中复制粘贴的,他们在其中将其称为q_incokable方法。
    // main.cpp

    #include "DummyElem.h"

    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

        QGuiApplication app(argc, argv);

        QList<QObject*> dataList;
        dataList.append(new DummyElem);
        dataList.append(new DummyElem);

        QQmlApplicationEngine engine;
        QQmlContext* context = engine.rootContext();
        context->setContextProperty("dataModel", QVariant::fromValue(dataList));

        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

        return app.exec();
    }

用ListView和一个委托描述一个qml布局,单击该委托将调用c ++方法。
    // main.qml

    import QtQuick 2.7
    import QtQuick.Window 2.2

    Window {
        visible: true

        ListView {
            anchors.fill: parent
            model: dataModel
            delegate: Component {
                Text {
                    text: model.dummy

                    MouseArea {
                        anchors.fill: parent
                        onClicked: {model.notifyStuff()}
                    }
                }
            }
        }
    }

这个问题很难调试,因为C ++类模型无法json-strigified,也无法获取其javascript entry()。我得到的错误是“未定义不是函数”,这也是很酷的。 我尝试在QML中注册Qt类型,但这也没有执行任何操作。

我使用的是Qt库版本5.9.4,但是QtCreator中的“所需的最低qt版本”框设置为“ Qt 5.6”。

1 个答案:

答案 0 :(得分:2)

您需要使用modelData。我不确定原因为何,最可能是因为QVariantList。您可以在this page上阅读更多内容。

Window {
    visible: true

    ListView {
        anchors.fill: parent
        model: dataModel
        delegate: Component {
            Text {
                text: modelData.dummy

                MouseArea {
                    anchors.fill: parent
                    onClicked: modelData.notifyStuff();
                }
            }
        }
    }
}

有趣的事实:这是我在Qt 5.11.3上遇到的错误:

TypeError: Property 'notifyStuff' of object QQmlDMObjectData(0x5585fe567650) is not a function

至少比undefined更具说服力,但我仍不能完全描述。