代码之家  ›  专栏  ›  技术社区  ›  Silex

如何从QC++中登记Quall的自定义类型

  •  1
  • Silex  · 技术社区  · 6 年前

    我有一个C++类 MyClass . 此类已注册为不可创建的类型,因此可以在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 . 此类创建 类名 物体。它被注册为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 类名 键入值并通过 . 这是我的 主.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*

    常量MyClass* const MyClass

    主要问题是如何将常量指针传递给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();
    }
    

    我用qt5.9.5。

    1 回复  |  直到 6 年前
        1
  •  3
  •   dtech    6 年前

    你所犯的错误清楚地表明了它是不起作用的 const 不管怎么说,你扭曲它,因为这不是API的设计方式,因为虽然你可以将非常量对象传递给常量函数,但是你不能做相反的事情,原因应该很明显。而且这个特定的API将有一个const-correct的方面并没有多大意义,至少在您使用的Qt版本中是这样的。

    if 检查QML,我不会屏住呼吸。。。

    存在只读属性的概念,但这实际上与常量不同,只是属性不能被赋予不同的值,如果值恰好是一个对象,它仍然可以被修改。

    所以如果你想让它成为常数,最简单的方法就是 公开接口以对该对象进行更改。

    而且,不需要注册 QObject 如果使用的是派生类型指针 qmlRegisterUncreatableType() , qmlRegisterType() , qmlRegisterSingletonType()