通过js库中定义的函数创建QML项目不会设置附加属性

时间:2017-01-31 15:32:15

标签: qt layout qml instantiation qtquick2

注意:以下测试用例中QtQuickUtils.js中的函数只是为了抽象出从组件URL创建QML对象所涉及的样板文件。

测试用例:

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"以及"创建obj"成功)。

如果我注释掉"Layout.fillWidth": true, "Layout.fillHeight": true行并在此之后取消注释,则会显示该项目。

此外,如果我将函数从JS文件移动到main.qml,则会显示该项目。

我尝试将JS文件中的函数移动到一个新的qml文件中(尝试将这个QML文件单独使用而不是单独使用),但是没有修复它。

知道我做错了什么,以及正确的解决方法吗?

1 个答案:

答案 0 :(得分: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对象的支持,带有通知,信号,绑定和所有好东西的属性。