Как создать QML тип?

Необходимо создать модели группы физических тел с возможностью редактирования их параметров без перекомпиляции. Решил для этого дела использовать QML - удобный синтаксис, можно объявлять функции для специфического обсчета параметров. Все классно, но хотелось бы максимально отстраниться от Quick.

Создал 2 класса:

class Model : public QObject
{
    Q_OBJECT

public:
    explicit Model(QObject *parent = Q_NULLPTR);
}

class Anode : public QObject
{
    Q_OBJECT

public:
    explicit Anode(QObject *parent = Q_NULLPTR);
}


Зарегистрировал типы в main.cpp:
int main(int argc, char *argv[])
{
    qmlRegisterType<Model>("Model", 1, 0, "Model");
    qmlRegisterType<Anode>("Model", 1, 0, "Anode");
    // ...
}


Создаю QML-файл:
import Model 1.0

Model {
    Anode {
    }
}


Загружаю qml-файл:
QQmlEngine engine;
QQmlComponent component(&engine);
component.loadUrl(QUrl("types/type1.qml"));
QObject *myObject = component.create();

получаю ошибку: QQmlComponent: Component is not ready

Загружаю по другому:
QQmlApplicationEngine engine;
engine.load(QUrl("types/type1.qml"));

получаю ошибку: types/type1.qml:4 Cannot assign to non-existent default property
Ну что за такое default property, имя которого не отображается в дебаге?
Стоит убрать объект Anode из Model, как все работает.

Окей, добавляю Q_PROPERTY(Anode* anode READ anode WRITE setAnode NOTIFY anodeChanged) в Model и правлю qml-файл:
import Model 1.0

Model {
    anode: Anode {
    }
}

получаю ошибку: types/type1.qml:4 Unexpected object assignment

Если оба этих объекта унаследовать не от QObject, а от QQuickItem, то все будет работать, но мне не нужен Item со всеми его x, y, width, height и т.д., особенно учитывая то, что эти параметры будут перекрываться некоторыми сущностями модели. Как победить этот Qml?
  • Вопрос задан
  • 908 просмотров
Решения вопроса 1
@wxmaper Автор вопроса
Такс, вот с этим разобрался:
Model {
    anode: Anode {
    }
}


Нужно было дополнительно объявить типы через макрос QML_DECLARE_TYPE:
QML_DECLARE_TYPE(Model)
QML_DECLARE_TYPE(Anode)


Но с этим ошибка по прежнему сохраняется...
Model {
    Anode {
    }
}


Похоже нужен еще какой-то магический макрос :)

Upd.
Очень хитрый Qt! Залез в QQuickItem и подглядел что там у него есть... А есть у него задействованный макрос Q_CLASSINFO.
В общем проблема решилась добавлением макроса таким образом:
class Model : public QObject
{
    Q_OBJECT

    Q_PROPERTY(Anode* anode READ anode WRITE setAnode NOTIFY anodeChanged)

    Q_PROPERTY(QObject* item WRITE addItem)
    Q_CLASSINFO("DefaultProperty", "item")

public:
    explicit Model(QObject *parent = Q_NULLPTR);

public slots:
    void addItem(QObject* item);
}


При создании объекта Anode вызывается метод Model::addItem. А там уже можно объекту Anode установить в качестве родителя объект Model.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Zifix
@Zifix Куратор тега Qt
Barbatum
Мне кажется вы пытаетесь использовать QML не общепринятым образом, потому приходится сразу лезть в дебри. Для начала советую прочитать вот этот цикл статей: https://habrahabr.ru/post/181712/
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы