Can't call slot or Q_INVOKABLE from QML in subclass of QQmlPropertyMap

ぃ、小莉子 提交于 2020-07-05 07:23:12

问题


I'm trying to test drive the QQmlPropertyMap class. It seems like it might work well for what I want, if I can subclass it. The documentation here even gives some rudimentary instructions on what to do for subclassing it. Said documentation also indicates that this class derives from QObject.

For what it's worth, I'm using QtCreator 2.6.1 on Qt 5.0.0 with QtQuick 2.0.

My main.qml:

import QtQuick 2.0

Rectangle {
    width: 360
    height: 360
    Text {
        text: owner.field
        anchors.centerIn: parent
    }
    MouseArea {
        anchors.fill: parent
        onClicked: {
            owner.testFunc();
        }
    }
}

My main.cpp:

#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
#include "TestMap.h"
#include <QQmlContext>

int main(int argc, char *argv[])
{
    TestMap* map = new TestMap();
    QGuiApplication app(argc, argv);
    QtQuick2ApplicationViewer viewer;
    QQmlContext* ctxt = viewer.rootContext();
    ctxt->setContextProperty("owner", map);
    viewer.setMainQmlFile(QStringLiteral("qml/TestMap/main.qml"));
    viewer.showExpanded();
    return app.exec();
}

My TestMap.h

#ifndef TESTMAP_H
#define TESTMAP_H

#include <QObject>
#include <QQmlPropertyMap>
#include <QDebug>

class TestMap: public QQmlPropertyMap  // QObject
{
    Q_OBJECT

public:
    TestMap(QObject* parent = 0): QQmlPropertyMap(this, parent)  // QObject(parent)
    {
        insert("field", "value");   // Comment this out
    }
    TestMap(const TestMap& value) { }
    virtual ~TestMap() {}

public slots:
    void testFunc()
    {
        qDebug() << "Success!";
    }
};

Q_DECLARE_METATYPE(TestMap)
#endif

When I run, I get a window saying "value", as I'd expect. But when I click on the window, I get a console output saying

TypeError: Property 'testFunc' of object TestMap(0xaaa0b8) is not a function

I've looked for similar problems, but all the search results are about people that forgot to include the Q_OBJECT macro. It must be something I'm doing wrong in the code, because if I make all the changes indicated in the comments of the TestMap file (and leave the main.cpp and main.qml exactly as is), I get the qDebug message I expect.

I'm not sure whether I'm supposed to Q_DECLARE_METATYPE or not (I think the 2-arg protected constructor is supposed to do it for me), but it doesn't work either way.

For the record, the only things I have to change to get it to work are:

1) Derive from QObject instead of QQmlPropertyMap.

2) Change the constructor to:

TestMap(QObject* parent = 0): QObject(parent) {}

And that's it. Since it works when I don't change anything about the main.cpp, main.qml, or the slot itself, I have to conclude it's nothing wrong with those. Can anyone tell me what I'm doing wrong?


回答1:


This is now fixed in Qt 5.1.0 and onwards. See the following codereview url for details:

https://codereview.qt-project.org/#change,57418



来源:https://stackoverflow.com/questions/15016258/cant-call-slot-or-q-invokable-from-qml-in-subclass-of-qqmlpropertymap

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!