2017-01-31 1 views
1

Примечание: Функция в QtQuickUtils.js в следующем тестовом сценарии предназначена только для абстрагирования шаблона, связанного с созданием объекта QML с URL-адреса компонента.Создание элемента QML через функцию, определенную в js-библиотеке, не устанавливает прикрепленные свойства

TestCase:

main.qml:

import QtQuick 2.6 
import QtQuick.Window 2.2 
import QtQuick.Layouts 1.3 
import "QtQuickUtils.js" as QtQuickUtils 

Window { 
    visible: true 
    width: 640 
    height: 480 

    GridLayout { 
     anchors.fill: parent 
     id: container 
     columns: 1 
    } 

    Component.onCompleted: { 
     QtQuickUtils.createObjectFromComponent("qrc:///MyItem.qml", container, { 
      "Layout.fillWidth": true, "Layout.fillHeight": true 
      // "width": 100, "height": 100 
     }); 
    } 
} 

MyItem.qml:

import QtQuick 2.0 

Rectangle { 
    color: "red" 
} 

QtQuickUtils.js:

.import QtQml 2.0 as Qml 
.pragma library 

function createObjectFromComponent(componentUrl, parent, properties) { 
    var component = Qt.createComponent(componentUrl); 
    function finishCreation() { 
     console.log("finishCreation"); 
     if (component.status === Qml.Component.Ready) { 
      var obj = component.createObject(parent, properties); 
      if (obj === null) { 
       console.log("Error creating object"); 
       return; 
      } 
      console.log("success in creating obj"); 
     } else if (component.status === Qml.Component.Error) { 
      console.log("Error loading component:", component.errorString()); 
      return; 
     } 
    } 
    if (component.status === Qml.Component.Ready) { 
     finishCreation(); 
    } else { 
     component.statusChanged.connect(function() { finishCreation(); }); 
    } 
} 

Это ничего не показывает (но печатаются «finishCreation» и «success in create obj»).

Если я прокомментирую строку "Layout.fillWidth": true, "Layout.fillHeight": true и раскомментирую одно после этого, элемент отображается.

Также, если я переведу функцию из файла JS в main.qml, элемент отображается.

Я попытался переместить функцию из файла JS в новый qml-файл (попробовал оба сделать этот файл QML singleton и не), но это не исправить.

Любая идея, что я делаю неправильно, и правильное исправление?

+0

'Поскольку они являются общими, файлы библиотеки .pragma не могут напрямую обращаться к объектам или свойствам объектов QML-компонента, хотя значения QML могут передаваться как параметры функции.' – dtech

+0

@ddriver: Я думаю, что у вас такая же путаница, как и в [этот вопрос] (http://stackoverflow.com/q/39497187). См. Принятый ответ там, я думаю, что очень вероятно, что вы узнаете что-то новое там. –

+0

Я лично не использую 'pragma library', вместо этого я использую синглтоны с функциями там, это позволяет использовать код плюс прямую поддержку свойств QML с уведомлениями и, естественно, иметь объекты QML, а не только объекты JS. – dtech

ответ

1

JS-файл не знает, что такое Layout, поэтому он не может его установить.

// in a JS file, shared or not 
function foo(item) { console.log(item.Layout) } // undefined 

Если бы вы были:

.import QtQuick.Layouts 1.3 as L // you can't import without "as" in .JS 
function foo(item) { console.log(item.L.Layout) } // and it suddenly works 

Так добавив небольшое неудобство, вы можете достичь цели, просто используя:

"L.Layout.fillWidth": true, "L.Layout.fillHeight": true 

Однако, он будет работать с одноплодной без что дополнительный шаг, потому что там вы можете сделать «анонимный» import QtQuick.Layouts 1.3, и внезапно жизнь снова станет легкой. Как я уже упоминал в комментариях, я действительно не вижу причины использовать pragma library, если, возможно, вы не используете некоторую стороннюю JS-библиотеку. Для всего остального QML-синглтоны гораздо более полезны, вы получаете «общую» часть, плюс поддержку объектов QML, свойств с уведомлениями, сигналами, привязками и всем этим хорошим материалом.

+0

Кроме того, мне показалось странным, что он не жалуется на то, что не может разрешить присоединенные свойства, будь то из JS или QML-файла, он неактуален по этому вопросу. Похоже, что еще один дизайн QML. – dtech

+0

Хм, я подумал, что при просмотре с JS 'Layout' в' foo.Layout.bar' рассматривается как просто свойство и, следовательно, его не нужно импортировать. Почему это не так? –

+0

Или, чтобы задать более четкий вопрос: в каких случаях синтаксис 'baz.qux' в JS не означает доступ к свойству' qux' объекта 'baz'? –

Смежные вопросы