Проблема
Я пытаюсь создать компонент 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.
Вопросы
Правильно ли я считаю, что объявление QQmlComponent уже оборачивает файл QML с типом Component
? Если нет, то как мне создать Component
компонент QML в C ++?
Почему происходит сбой программы при создании вложенного пользовательского компонента? Нужно ли создавать компонент другими способами?
Любая помощь и исправления фундаментальных заблуждений будет принята с благодарностью. Спасибо.