Function 从QML组件导出函数,并访问中继器
我有一个嵌套QML组件的层次结构,并希望在内部组件中设置一些值(例如,项目的颜色) 我想我需要做的是将参数传递给下一个内部组件,然后这些组件将这些数据的一部分转发给它们的孩子,等等,直到到达接收者。这将尊重封装的想法 然而,我很难在QML/JS中实现这一点。首先,我不知道如何导出一个函数,以便可以从组件外部调用它(在属性变量中?我尝试了这个方法,但得到了一个错误“JavaScript声明在脚本元素外部”)。其次,我不知道如何为中继器中的元素调用函数。最后,也许有一种更直接的方法来实现这一点 以下是一个MWE,它传达了我正在努力实现的目标: 文件mwe.qmlFunction 从QML组件导出函数,并访问中继器,function,qt,qml,Function,Qt,Qml,我有一个嵌套QML组件的层次结构,并希望在内部组件中设置一些值(例如,项目的颜色) 我想我需要做的是将参数传递给下一个内部组件,然后这些组件将这些数据的一部分转发给它们的孩子,等等,直到到达接收者。这将尊重封装的想法 然而,我很难在QML/JS中实现这一点。首先,我不知道如何导出一个函数,以便可以从组件外部调用它(在属性变量中?我尝试了这个方法,但得到了一个错误“JavaScript声明在脚本元素外部”)。其次,我不知道如何为中继器中的元素调用函数。最后,也许有一种更直接的方法来实现这一点 以下
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.2
Window {
id: root
visible: true
width: 640
height: 480
ColumnLayout {
Mwe2 {
id: m2
}
Button {
text: "Test"
onClicked: {
var colors = [];
var letters = '0123456789ABCDEF';
for (var i = 0; i<12; i++) {
var color = '#';
for (var j = 0; j < 6; j++) {
color += letters[Math.floor(Math.random() * 16)];
}
colors.push(color);
}
console.log(colors);
m2.setColor(colors);
// call function in m2 with colors as argument
}
}
}
}
文件Mwe3.qml:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.2
RowLayout {
spacing: 2
Repeater {
id: rect2
model: 4
Rectangle {
color: 'orange'
width: 50
height: 20
}
}
// function that sets the colors in the repeater items,
// using something like rect2.itemAt(i).child(0).color = ...
}
这里有一条路。注意,我将
ColumnLayout
部分移到了Mwe3.qml中,使其成为委托的一部分——这大大简化了访问。在那之后就相当直截了当了,只要绕着中继器的孩子们转一圈就行了。“mwe1.qml”保持不变(除了修复注释中提到的“setColors”打字错误),所以我不会发布它
Mwe2.qml
import QtQuick 2.9
import QtQuick.Layouts 1.2
RowLayout {
spacing: 2
Repeater {
id: rect
model: 3
delegate: Mwe3 { }
}
function setColors(colors) {
// loops over repeater items, passing
// slice of colors array to function in m3
for (var i=0; i < rect.count; ++i)
rect.itemAt(i).setColors(colors.slice(i, i+3));
}
}
导入QtQuick 2.9
导入QtQuick.Layouts 1.2
行布局{
间距:2
中继器{
id:rect
型号:3
代表:Mwe3{}
}
函数设置颜色(颜色){
//在中继器项目上循环,传递
//要在m3中运行的颜色数组切片
对于(变量i=0;i
Mwe3.qml
import QtQuick 2.9
import QtQuick.Layouts 1.2
ColumnLayout {
Rectangle {
color: 'red'
width: 50
height: 20
}
RowLayout {
spacing: 2
Repeater {
id: rect2
model: 4
delegate: Rectangle {
color: 'orange'
width: 50
height: 20
}
}
}
function setColors(colors)
{
console.log(colors);
for (var i=0; i < rect2.count && i < colors.length; ++i) {
console.log(rect2.itemAt(i));
rect2.itemAt(i).color = colors[i];
}
}
}
导入QtQuick 2.9
导入QtQuick.Layouts 1.2
列布局{
长方形{
颜色:“红色”
宽度:50
身高:20
}
行布局{
间距:2
中继器{
id:rect2
型号:4
代表:矩形{
颜色:“橙色”
宽度:50
身高:20
}
}
}
函数设置颜色(颜色)
{
控制台日志(颜色);
对于(变量i=0;i
您可能还对使用数据模型的替代方法感兴趣。我在这里发布了一个这样的例子(也经常使用颜色):Typo:change to
m2.setColors(colors)我认为你的设计很差,你的最终目标是什么?为什么你们有嵌套的中继器。给出一个真实的例子,因为你虚构的例子非常令人困惑。这很有效,谢谢。然而,在我的应用程序中,ColumnLayout必须保持在Mwe3中(对象更复杂,这只是一个精简的mwe)。在这种情况下,如何最好地访问Mwe3?我设法将索引编入“children”或布局,但这似乎不是很便于携带。通过id访问会更容易,但我可以这样做吗?@user52366请解释/显示您的用例,说明为什么ColumnLayout不是委托的一部分。因为我不明白你想做什么,所以很难/不可能/浪费时间随意提出建议。至于id
属性,当引用作为模型视图代理的项(如Repeater)时,它是无用的(而且令人困惑的)——它们显然不再是唯一的,它们不能/不应该是动态的。请记住,在中继器创建代理之前,代理实际上并不存在。或者我也不明白你的意思。同样要指出的是,中继器的委托
是默认属性,这意味着放置在中继器内的任何项目
都将成为委托——这正是发布的MRE所做的。
import QtQuick 2.9
import QtQuick.Layouts 1.2
ColumnLayout {
Rectangle {
color: 'red'
width: 50
height: 20
}
RowLayout {
spacing: 2
Repeater {
id: rect2
model: 4
delegate: Rectangle {
color: 'orange'
width: 50
height: 20
}
}
}
function setColors(colors)
{
console.log(colors);
for (var i=0; i < rect2.count && i < colors.length; ++i) {
console.log(rect2.itemAt(i));
rect2.itemAt(i).color = colors[i];
}
}
}