通过 js 库中定义的函数创建 QML 项不会设置附加属性
Creating QML Item via function defined in js library doesn't set attached properties
注意:以下测试用例中QtQuickUtils.js
中的函数只是抽象出从组件创建QML对象所涉及的样板URL .
测试用例:
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 creating obj")。
如果我注释掉 "Layout.fillWidth": true, "Layout.fillHeight": true
行并取消注释后一行,则会显示该项目。
此外,如果我将函数从 JS 文件移动到 main.qml,则会显示该项目。
我尝试将函数从 JS 文件移动到一个新的 qml 文件中(尝试将此 QML 文件设为单例和非单例),但这并没有解决问题。
知道我做错了什么吗,以及正确的解决方法?
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
然而,它可以在没有额外步骤的情况下使用单例,因为在那里你可以做一个 "anonymous" import QtQuick.Layouts 1.3
,突然间生活又变得轻松了。正如我在评论中提到的,我真的没有理由使用 pragma library
,除非您可能正在使用某些第三方 JS 库。对于其他一切,QML 单例更有用,你得到了 "shared" 部分,加上对 QML 对象的支持、带有通知的属性、信号、绑定和所有这些好东西。
注意:以下测试用例中QtQuickUtils.js
中的函数只是抽象出从组件创建QML对象所涉及的样板URL .
测试用例:
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 creating obj")。
如果我注释掉 "Layout.fillWidth": true, "Layout.fillHeight": true
行并取消注释后一行,则会显示该项目。
此外,如果我将函数从 JS 文件移动到 main.qml,则会显示该项目。
我尝试将函数从 JS 文件移动到一个新的 qml 文件中(尝试将此 QML 文件设为单例和非单例),但这并没有解决问题。
知道我做错了什么吗,以及正确的解决方法?
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
然而,它可以在没有额外步骤的情况下使用单例,因为在那里你可以做一个 "anonymous" import QtQuick.Layouts 1.3
,突然间生活又变得轻松了。正如我在评论中提到的,我真的没有理由使用 pragma library
,除非您可能正在使用某些第三方 JS 库。对于其他一切,QML 单例更有用,你得到了 "shared" 部分,加上对 QML 对象的支持、带有通知的属性、信号、绑定和所有这些好东西。