Как выставить фабрику для объектов-значений в QML? - PullRequest
0 голосов
/ 24 августа 2018

Я хочу создать объекты-значения без конструкторов и сеттеров по умолчанию, которые могут быть созданы из QML. Я пришел к реализации Factory как обходной путь, который будет передан как одиночный в QML. Но когда я пытался использовать его, я получаю сообщение «Ошибка: тип возврата неизвестного метода: точка», и когда я закрываю сбой приложения, происходящий с сообщением «free (): неверный указатель» в журналах.

Point.h:

#ifndef POINT_H
#define POINT_H

#include <QObject>

struct Point
{
    Q_GADGET
    Q_PROPERTY(int x READ getX CONSTANT)
    Q_PROPERTY(int y READ getY CONSTANT)

public:
    Point(int x, int y) : x(x), y(y) {

    }

    Point(const Point& that) = default;
    Point& operator=(const Point& that) = default;

    int getX() {
        return this->x;
    }

    int getY() {
        return this->y;
    }

    Q_INVOKABLE QString getCoordinates() {
        return QString("x=%1; y=%2").arg(this->x, this->y);
    }

private:
    int x;
    int y;
};

#endif // POINT_H

Factory.h:

#ifndef FACTORY_H
#define FACTORY_H

#include <QObject>

#include "point.h"

class Factory : public QObject {
    Q_OBJECT
    Q_DISABLE_COPY(Factory)

public:
    static Factory* instance() {
        static Factory factory;
        return &factory;
    }

    Q_INVOKABLE Point newPoint(int x, int y) {
        return Point(x, y);
    }

private:
    Factory() {

    }
};

#endif // FACTORY_H

main.cpp:

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QObject>

#include "factory.h"
#include "point.h"


int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    qmlRegisterUncreatableType<Point>("test", 1, 0, "Point", "error: no default constructor");
    qmlRegisterSingletonType<Factory>("test", 1, 0, "Factory",
                                      [](QQmlEngine* engine, QJSEngine* scriptEngine) -> QObject* {
        Q_UNUSED(engine)
        Q_UNUSED(scriptEngine)

        return Factory::instance();
    });

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

main.qml:

import QtQuick 2.9
import QtQuick.Controls 2.3

import test 1.0

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Component.onCompleted: {
        var point = Factory.newPoint(5, 10);
        console.log("completed")
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...