【问题标题】:Can't invoke Qt c++ method in QML ListView无法在 QML ListView 中调用 Qt c++ 方法
【发布时间】:2019-01-10 07:19:29
【问题描述】:

我有一个 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 条目()。我得到的错误是“未定义不是函数”,这也很酷。 我尝试在 QML 中注册 Qt 类型,但这也没有做任何事情。

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

【问题讨论】:

  • 应该是onClicked: {model.dummy.notifyStuff()} ?您的列表没有“notifyStuff”功能...这是复制和粘贴错误吗?
  • @Mailerdaimon 虚拟是一个字符串属性,我不明白这有什么意义?
  • 哦..你是对的。抱歉,我需要一杯咖啡。

标签: c++ qt qml


【解决方案1】:

您需要使用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 更有说服力,但我想说的仍然不是完全的描述性。

【讨论】:

  • 谢谢,这确实有效!感谢您的文档文章,我只是想知道 modelData 有什么区别。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-14
  • 2019-06-07
  • 1970-01-01
  • 2014-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多