Ошибка: Qt.createQmlObject(): компонент не готов

#qt #dynamic #qml #components #qt-quick

#qt #динамический #qml #Компоненты #qt-быстрый

Вопрос:

Я хочу создать элемент QML из строки QML, используя функцию Qt.createQmlObject(), как в примере, но в первый раз получаю сообщение об ошибке: «Ошибка: Qt.createQmlObject (): компонент не готов», во второй раз элемент создан правильно, что не так?

Вы можете видеть — я пробовал разные элементы: элемент, Прямоугольник, компонент (только у одного есть свойство «статус»)

тестовое приложение: main.cpp:

   #include <QApplication>
  #include <QWSServer>
  #include <QDeclarativeView>

  int main(int argc, char *argv[])
  {
    QApplication a(argc, argv, QApplication::GuiServer);

    QDeclarativeView view;
    view.setMinimumSize(100,100);
    view.setResizeMode(QDeclarativeView::SizeRootObjectToView);
    view.show();
    view.setSource(QUrl::fromUserInput("qrc:/createFromStringTest.qml"));

    return a.exec();
  }
 

createFromStringTest.qml:

         import QtQuick 1.1

        Rectangle {
            id: rootRectangle
            objectName: "rootRectangle"
            anchors.centerIn: parent
            anchors.fill: parent
            color: "gray"
            border.width: 5
            border.color: "black"
            width: 50
            height: 50

            property int testCount: 0

            MouseArea {
                anchors.fill: parent
                onClicked: {
                    testCount  =1;
                    console.log("====================== Runing test " testCount " ======================");
                    tests()
                }
            }

            // what is right?
            Item{
                id: parentItem
                objectName: "parentItem"
                Component.onCompleted: {
                    console.log("parentItem loaded");
                }
            }

            Component {
                id: parentComponent
                Item {
                    id: parentComponentItem
                    Component.onCompleted: {
                        console.log("parentComponentItem loaded");
                    }
                }
            }

            property list<Item> parentListItem
            property list<Component> parentListComponent

            Rectangle {
                id: parentRectangle
                objectName: "parentRectangle"
                Component.onCompleted: {
                    console.log("parentRectangle loaded");
                }
            }

            Component.onCompleted: {
                console.log("rootRectangle loaded ");
            }

            Component.onDestruction: {
                console.log("rootRectangle destroyed ");
            }

            function tests(){
                try{
                    var newObjectparentItem = Qt.createQmlObject('import QtQuick 1.1; Rectangle {objectName: "dynparentItem";anchors.centerIn: parent; anchors.fill: parent; border.width: 10; border.color: "red";}',parentItem,"parentItem:");
                    console.log("parentItem OK ");
                }catch(e){
                    console.log("parentItem error: " e);
                }

                try{
                    var newObjectparentComponent = Qt.createQmlObject('import QtQuick 1.1; Rectangle {objectName: "dynparentComponent";anchors.centerIn: parent; anchors.fill: parent; border.width: 10; border.color: "red";}',parentComponent,"parentComponent:");
                    console.log("parentComponent OK ");
                }catch(e){
                    console.log("parentComponent error: " e);
                }

                try{
                    var newObjectparentComponentItem = Qt.createQmlObject('import QtQuick 1.1; Rectangle {objectName: "dynparentComponentItem";anchors.centerIn: parent; anchors.fill: parent; border.width: 10; border.color: "red";}',parentComponentItem,"parentComponentItem:");
                    console.log("parentComponentItem OK ");
                }catch(e){
                    console.log("parentComponentItem error: " e);
                }

                try{
                    var newObjectparentListItem = Qt.createQmlObject('import QtQuick 1.1; Rectangle {objectName: "dynparentListItem";anchors.centerIn: parent; anchors.fill: parent; border.width: 10; border.color: "red";}',parentListItem,"parentListItem:");
                    console.log("parentListItem OK ");
                }catch(e){
                    console.log("parentListItem error: " e);
                }

                try{
                    var newObjectparentListComponent = Qt.createQmlObject('import QtQuick 1.1; Rectangle {objectName: "dynparentListComponent";anchors.centerIn: parent; anchors.fill: parent; border.width: 10; border.color: "red";}',parentListComponent,"parentListComponent:");
                    console.log("parentListComponent OK ");
                }catch(e){
                    console.log("parentListComponent error: " e);
                }

                try{
                    var newObjectparentRectangle = Qt.createQmlObject('import QtQuick 1.1; Rectangle {objectName: "dynparentRectangle";anchors.centerIn: parent; anchors.fill: parent; border.width: 10; border.color: "red";}',parentRectangle,"parentRectangle:");
                    console.log("parentRectangle OK ");
                }catch(e){
                    console.log("parentRectangle error: " e);
                }
            }
        }
 

вывод:

 Qml debugging is enabled. Only use this in a safe environment!
rootRectangle loaded 
parentRectangle loaded
parentItem loaded
====================== Runing test 1 ======================
parentItem error: Error: Qt.createQmlObject(): Component is not ready
parentComponent error: Error: Qt.createQmlObject(): Component is not ready
parentComponentItem error: ReferenceError: Can't find variable: parentComponentItem
parentListItem error: Error: Qt.createQmlObject(): Missing parent object
parentListComponent error: Error: Qt.createQmlObject(): Missing parent object
parentRectangle error: Error: Qt.createQmlObject(): Component is not ready
====================== Runing test 2 ======================
parentItem OK 
parentComponent OK 
parentComponentItem error: ReferenceError: Can't find variable: parentComponentItem
parentListItem error: Error: Qt.createQmlObject(): Missing parent object
parentListComponent error: Error: Qt.createQmlObject(): Missing parent object
parentRectangle OK 
rootRectangle destroyed 
 

Используется Qt 4.8

Комментарии:

1. Проверьте сообщение об ошибке.

2. @ddriver это в теме, но что это значит и как избежать ошибки, если ParentComponent.status всегда === 1 (готов) ? Почему во второй раз отмечается ошибка?

Ответ №1:

По моему опыту, я получил ошибку «Компонент не готов» при динамическом создании объекта с помощью Qt.createComponent Component.CreateObject, и в компоненте есть ошибка QML.

Один из способов обнаружить ошибку — статически добавить экземпляр этого компонента в ваше приложение QML, чтобы ошибка с номером строки выводилась при запуске приложения.

Ответ №2:

Ошибка в третьем аргументе функции Qt.createQmlObject(строка QML, идентификатор родителя, имя файла) имя файла в моем примере состоит из символа «:» — без него работает, как ожидалось!

Ответ №3:

Для случая, подобного вашему, используйте Qt.createComponent для динамической инициализации используемого вами компонента. После инициализации компонента вы можете вызвать компонент.Создайте объект. Или вы могли бы использовать для этого один родительский компонент : parentComponent.CreateObject(QmlItem, "QML properties") . Обычно я использую Qt.createQmlObject для выполнения динамических действий с окном QML сразу в этом файле QML и не создаю для него никакого нового контекста QML.

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

Комментарии:

1. Мне нужно создать элемент из строки, полученной из сети.