Я хочу вызвать функцию C ++ из QML / JS, которая принимает класс C ++ (объект данных), созданный в QML в качестве аргумента. Программа компилируется и запускается, однако, когда я пытаюсь вызвать функцию C ++ из QML / JS, я получаю следующую ошибку:
"Не удалось преобразовать аргумент 0 в" "onClicked@qrc: / main.qml : 26 "" Передача несовместимых аргументов в функции C ++ из JavaScript опасна и не рекомендуется. " «Это вызовет JavaScript TypeError в будущих выпусках Qt!»
Я перепробовал все комбинации вызова по ссылке / значению / указателю, а также несколько вариантов с Q_GADGET и Q_OBJECT, но я просто не могу получить это работает.
Мой минимальный пример с типом данных C ++ на основе QObject, а также всеми комбинациями вызовов выглядит следующим образом:
Тип данных C ++
#include <QObject>
#include <QDebug>
//Data type which should be instantiated in QML
class CustomDataObject : public QObject{
Q_OBJECT
Q_PROPERTY(int exampleValue MEMBER exampleValue)
public:
int exampleValue;
explicit CustomDataObject(QObject * parent = nullptr) : QObject(parent) {}
~CustomDataObject() = default;
CustomDataObject(const CustomDataObject& blob) {}
};
Q_DECLARE_METATYPE(CustomDataObject);
C ++ Класс с функцией для вызова
//Class with function called from QML
class UniqueDataBackend : public QObject {
Q_OBJECT
public:
//Call with native data type (works)
Q_INVOKABLE void processNativeObject(int value) {
qDebug() << "C++: Nativ Value: " << value;
}
//Call by value (does not work)
Q_INVOKABLE void processDataObjectByValue(const CustomDataObject data) {
qDebug() << "C++: Data Object Value: " << data.exampleValue;
}
//Call by reference (does not work)
Q_INVOKABLE void processDataObjectByReference(const CustomDataObject & data) {
qDebug() << "C++: Data Object Value: " << data.exampleValue;
}
//Call by pointer (does not work)
Q_INVOKABLE void processDataObjectByPointer(const CustomDataObject * data) {
qDebug() << "C++: Data Object Value: " << data->exampleValue;
}
UniqueDataBackend(QObject * parent = nullptr) : QObject(parent) {}
~UniqueDataBackend() = default;
UniqueDataBackend(const UniqueDataBackend& blob) {}
};
Q_DECLARE_METATYPE(UniqueDataBackend);
main. cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QQmlEngine>
#include "CustomStruct.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
//Register types for use in QML
qRegisterMetaType<CustomDataObject>();
qmlRegisterType<CustomDataObject>("Custom.Types", 1, 0, "CustomDataObject");
//Register intances for use in QML
engine.rootContext()->setContextProperty("UniqueDataBackend", new UniqueDataBackend());
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
QML-файл (main.qml)
import QtQuick 2.12
import QtQuick.Controls 2.12
import Custom.Types 1.0
ApplicationWindow {
id: window
width: 400
height: 300
visible: true
CustomDataObject {
id: customData
exampleValue: 84
}
Button {
text: "Click me!"
anchors.fill: parent
onClicked: {
console.log("QML: Calling c++ function with native data type!")
UniqueDataBackend.processNativeObject(42)
console.log("QML: Checking value of custom data type in javascript: " + customData.exampleValue)
console.log("QML: Calling c++ function by value with custom data type!")
UniqueDataBackend.processDataObjectByValue(customData)
console.log("QML: Calling c++ function by reference with custom data type!")
UniqueDataBackend.processDataObjectByReference(customData)
console.log("QML: Calling c++ function by pointer with custom data type!")
UniqueDataBackend.processDataObjectByPointer(customData)
}
}
}
Вывод
qml: QML: Calling c++ function with native data type!
C++: Nativ Value: 42
qml: QML: Checking value of custom data type in javascript: 84
qml: QML: Calling c++ function by value with custom data type!
"Could not convert argument 0 at"
"onClicked@qrc:/main.qml:26"
"Passing incompatible arguments to C++ functions from JavaScript is dangerous and deprecated."
"This will throw a JavaScript TypeError in future releases of Qt!"
C++: Data Object Value: 0
qml: QML: Calling c++ function by reference with custom data type!
"Could not convert argument 0 at"
"onClicked@qrc:/main.qml:29"
"Passing incompatible arguments to C++ functions from JavaScript is dangerous and deprecated."
"This will throw a JavaScript TypeError in future releases of Qt!"
C++: Data Object Value: -842150451
qml: QML: Calling c++ function by pointer with custom data type!
qrc:/main.qml:32: Error: Unknown method parameter type: const CustomDataObject*
Я предполагаю, что это проблема с пользовательским типом данных, так как я могу вызвать функцию с родными типами данных без проблем, но для жизни я не могу понять это.
Большое спасибо за вашу помощь / комментарии!