我有一个名为MyClass
的C ++类。此类已注册为不可创建的类型,因此可以在QML中通过名称进行引用。
MyClass.h
:
#pragma once
#include <QObject>
class MyClass : public QObject {
Q_OBJECT
public:
static void initQML();
MyClass();
MyClass(const MyClass &myClass);
~MyClass();
Q_INVOKABLE void printText();
};
MyClass.cpp
:
#include "MyClass.h"
#include <QtQml>
#include <QDebug>
#include <QMetaType>
/*static*/ void MyClass::initQML() {
qmlRegisterUncreatableType<const MyClass>("Test", 1, 0, "MyClass", "Don't create it");
qRegisterMetaType<const MyClass*>("const MyClass*");
}
MyClass::MyClass() {
qDebug() << "Constructor called.";
}
MyClass::MyClass(const MyClass &myClass) {
qDebug() << "Copy constructor called.";
}
MyClass::~MyClass() {
qDebug() << "Destructor called.";
}
void MyClass::printText() {
qDebug() << "This a sample text.";
}
我还有另一个班级,叫做MyClassFactory
。此类创建MyClass
对象。它已注册为QML的单例类型。
MyClassFactory.h
:
#pragma once
#include "MyClass.h"
#include <QObject>
class MyClassFactory : public QObject {
Q_OBJECT
public:
static void initQML();
MyClassFactory();
public slots:
static const MyClass *makeDefaultMyClass();
};
MyClassFactory.cpp
:
#include "MyClassFactory.h"
#include <QtQml>
#include <QQmlEngine>
#include <QJSEngine>
QObject *simpleQmlRegisterSingletonTypeCallback(QQmlEngine *, QJSEngine *) {
return new MyClassFactory();
}
/*static*/ void MyClassFactory::initQML() {
qmlRegisterSingletonType<MyClassFactory>("Test", 1, 0, "MyClassFactory",
simpleQmlRegisterSingletonTypeCallback);
}
MyClassFactory::MyClassFactory() {}
/*static*/ const MyClass* MyClassFactory::makeDefaultMyClass() {
return new MyClass();
}
在我的main.qml
中,创建一个MyClass
类型的属性,并通过MyClassFactory
将一个值绑定到该属性。这是我的main.qml
:
import QtQuick 2.9
import QtQuick.Controls 2.2
import Test 1.0
ApplicationWindow {
visible: true
width: 480
height: 272
property MyClass myClass: MyClassFactory.makeDefaultMyClass()
Button {
anchors.centerIn: parent
text: "Create MyClass"
onClicked: myClass.printText()
}
}
构建并运行代码时,在控制台中出现以下错误:
qrc:/main.qml:12: Error: Unknown method return type: const MyClass*
如果我将const MyClass*
注册为元类型,则此错误消失,但是我得到另一个错误:
qrc:/main.qml:12:31: Unable to assign const MyClass* to MyClass*
首先,如果我已经将const MyClass*
注册为QML(不可创建)类型,为什么必须将const MyClass
注册为元类型?
主要问题是如何将const指针传递给QML?
例如,这是我的main.cpp
:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "MyClass.h"
#include "MyClassFactory.h"
int main(int argc, char *argv[])
{
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
// Init
MyClass::initQML();
MyClassFactory::initQML();
// Main loop
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
我使用Qt 5.9.5。
答案 0 :(得分:2)
您遇到的错误表明,无论如何扭曲它,它都无法与let obj = { a: 1, b: "b", c: undefined, d: null };
let cleanObj = {};
Object.keys(obj).forEach(val => {
const newVal = obj[val];
cleanObj = newVal ? { ...cleanObj, [val]: newVal } : cleanObj;
});
console.info(cleanObj);
一起使用,因为这不是API的设计方式,因为可以将非const对象传递给const函数,您不能做相反的事情,原因应该显而易见。而且,至少在您使用的Qt版本中,这个特定的API具有const正确的一面并没有多大意义。
直到最近,JS才真正没有常量的概念。它是在ECMA 2015中引入的,但是无论如何QML目前仍不支持该规范。 Qt 5.12会实现它,但是即使如此,我仍然怀疑它从一开始就将与C ++集成在一起。正确地传播const正确性将是一件好事,但是再一次,看到空指针变量仍然如何通过QML中的const
检查,我不会屏住呼吸...
存在只读属性的概念,但实际上与常量不同,只是不能为属性分配其他值的属性,如果该值恰好是对象,则仍可以对其进行修改。
>因此,如果要使其成为常量,最简单的操作是不公开接口以对该对象进行更改。
此外,如果您对这些类型使用if
,QObject
,qmlRegisterUncreatableType()
或类似的类型,则不需要注册qmlRegisterType()
派生类型指针。 / p>