Создание вложенного пользовательского компонента QML `Component` в классе C ++ - PullRequest
0 голосов
/ 03 января 2019

Проблема

Я пытаюсь создать компонент QML (и под компонентом я имею в виду компонент QML типа Component, который используется свойством Loader * sourceComponent) в классе C ++ и передать его в файл QML. Я использую Loader, в частности, для динамического изменения одной области представления на основе взаимодействия пользователя с пользовательским интерфейсом в другом месте этого представления. Вот как я подхожу к реализации:

DynamicLoader.h

class DynamicLoader: public QQuickItem {
    Q_OBJECT
    Q_PROPERTY(QObject *mainComp READ getMainComp NOTIFY mainCompChanged)

public:
    DynamicLoader(QQuickItem *parent = Q_NULLPTR);

    QObject* getMainComp() const;

private:
    QObject* m_mainComp;

    QObject* createComponent();

signals:
    void mainCompChanged();

};

DynamicLoader.cpp

DynamicLoader::DynamicLoader(QQuickItem* parent)
    : QQuickItem(parent)
    , m_mainComp(new QObject(this)) {
    m_mainComp = createCustomComponent();
}

QObject *DynamicLoader::getMainComp() const {
    return m_mainComp;
}

QObject* DynamicLoader::createComponent() {
    QQmlEngine engine;

    QQmlComponent component(&engine,                     
    QUrl::fromLocalFile("://imports/components/CustomComponent.qml"));
    QObject* object = component.create();
    Q_ASSERT(object);

    QQuickItem* childItem = qobject_cast<QQuickItem*>(object);
    childItem->setParent(this);
    return childItem;
}

CustomComponent.qml

Component {
    CustomTextBox {
        text: "Custom Text"
    }
}

CustomTextBox.qml

import QtQuick 2.0

Item {
    property int containerWidth: 580
    property alias text: customText.text

    anchors.fill: parent

    Text {
        id: customText
        text: "Default Text"
        anchors.top: parent.top
        anchors.horizontalCenter: parent.horizontalCenter
        width: parent.width
        verticalAlignment: Text.AlignVCenter
        horizontalAlignment: Text.AlignHCenter
        font.weight: Font.Bold
        font.pointSize: 100
        color: "white"
    }
}

Это, однако, приводит к сбою программы со следующим сообщением об ошибке:

QQmlComponent: Component is not ready и происходит сбой при Q_ASSERT.

Другие выводы

Эта же ошибка возникает, даже если CustomComponent.qml заменено просто Component {}. Когда я обнаружил это, я подозревал, что, возможно, QQmlComponent уже упаковывает файл QML с типом Component (пожалуйста, исправьте меня, если я ошибаюсь), поэтому я пошел дальше и преобразовал файл в:

Item {
    CustomTextBox {
        text: "Custom Text"
    }
}

и получил ту же ошибку.

Только когда я изменяю файл на следующий, он не выдает ошибку:

Item {
    Item {
    }
}

Наконец, ошибка не возникает, когда я полностью реализую CustomComponent.qml в QML.

Вопросы

  1. Правильно ли я считаю, что объявление QQmlComponent уже оборачивает файл QML с типом Component? Если нет, то как мне создать Component компонент QML в C ++?

  2. Почему происходит сбой программы при создании вложенного пользовательского компонента? Нужно ли создавать компонент другими способами?

Любая помощь и исправления фундаментальных заблуждений будет принята с благодарностью. Спасибо.

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