Как зарегистрировать пользовательский тип в QML, если он передан как const из C ++ - PullRequest
0 голосов
/ 12 октября 2018

У меня есть класс 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.Этот класс создает 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* как метатипа, если я уже зарегистрировал const MyClass как тип QML (не поддающийся обработке)?

Главный вопрос - как передать константный указатель на 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.

1 Ответ

0 голосов
/ 16 октября 2018

Ошибки, которые вы получаете, дают понять, что он не будет работать с const, в любом случае, вы его закручиваете, потому что это не так, как разработан API, потому что, хотя вы можете передавать неконстантные объекты в константные функции, выне может сделать обратное по причинам, которые должны быть очевидны.И не имеет особого смысла, что этот конкретный API будет иметь правильную константную сторону, по крайней мере в используемой вами версии Qt.

До недавнего времени у JS действительно не былоПонятие постоянных.Он был представлен в ECMA 2015, но эта спецификация в настоящее время все еще не поддерживается в QML.Qt 5.12 будет реализовывать его, но даже тогда, я сомневаюсь, что он будет интегрирован со стороной C ++ с самого начала.Правильно распространять правильность констант было бы неплохо, но, опять же, видя, как варианты нулевого указателя все еще проходят if проверки в QML, я бы не задерживал дыхание ...

СуществуетПонятие только для чтения свойств, но это на самом деле не то же самое, что константы, это просто свойства, которые не могут быть назначены другому значению, если значение оказывается объектом, оно все равно может быть изменено.

Так чтоЕсли вы хотите, чтобы она была константой, проще всего просто , а не предоставить интерфейс для внесения изменений в этот объект.

Кроме того, не должно быть необходимости регистрироваться QObject указатели производных типов, если вы используете qmlRegisterUncreatableType(), qmlRegisterType(), qmlRegisterSingletonType() или аналогичные для этих типов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...