Nullpointer passed when using pointer to const object as parameter for c++ method called from qml
-
Consider the following minimal example:
main.cpp#include <QApplication> #include <QQmlApplicationEngine> #include <QtQml> #include "test.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); qmlRegisterType<Test>("nanotron.test.test", 1, 0, "Test"); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); return app.exec(); }
test.h
#ifndef TEST_H #define TEST_H #include <QObject> class Test : public QObject { Q_OBJECT Q_PROPERTY(int member MEMBER m_member NOTIFY memberChanged) public: explicit Test(QObject *parent = 0); Q_INVOKABLE void print(const Test* other); signals: void memberChanged(); public slots: private: int m_member; }; Q_DECLARE_METATYPE(const Test*) #endif // TEST_H
test.cpp
#include "test.h" #include <QDebug> Test::Test(QObject *parent) : QObject(parent) { } void Test::print(const Test *other) { qWarning() << "Value of test object's meber:" << other->m_member; }
main.qml
import QtQuick 2.5 import QtQuick.Controls 1.4 import nanotron.test.test 1.0 ApplicationWindow { visible: true width: 640 height: 480 title: qsTr("Hello World") Component { id: testComponent Test { } } menuBar: MenuBar { Menu { title: qsTr("File") MenuItem { text: qsTr("&Open") onTriggered: { var test1 = testComponent.createObject() var test2 = testComponent.createObject() test1.member = 4711 test2.print(test1) } } MenuItem { text: qsTr("Exit") onTriggered: Qt.quit(); } } } Label { text: qsTr("Hello World") anchors.centerIn: parent } }
When I run this and click on File -> Open the program crashes. In the debugger I can see that NULL is passed to the print method of the test class. I can trace it back to the qt_metacall method of the moc class that is generated for test.
When I remove the const from the parameter in print, i.e changeQ_INVOKABLE void print(const Test* other);
to
Q_INVOKABLE void print(Test* other);
and
void Test::print(const Test *other)
to
void Test::print(Test *other)
and
Q_DECLARE_METATYPE(const Test*)
to
Q_DECLARE_METATYPE(Test*)
it works fine.
Can someone explain this to me? Is it a bug? Is it expected? Is it possible to use pointers to const objects when passing parameters from QML to c++?
-
Hi and welcome to devnet,
You should use
qmlRegisterType<const Test>("nanotron.test.test", 1, 0, "Test");
-
Thank you very much!
I guessed it must be something trivial. Of course I have to register the exact type that I want to use with the meta type system.
I'm not sure if like the fact that registering the wrong type leads to a null pointer being passed. Do you happen to know what is the reason for that? Is it the unchecked result of a dynamic cast? I certainly would prefer, if an exception could be raised in that case. Do you think this would be possible to add? -
You're welcome !
No I don't, sorry, I haven't touched the internals of the QtQuick/QML modules.
That's a question you should bring to the interest mailing list. You'll find there Qt's developers/maintainers(this forum is more user oriented)