【问题标题】:Export function from QML Component, and access Repeater从 QML Component 导出函数,并访问 Repeater
【发布时间】:2019-11-26 02:33:03
【问题描述】:

我有一个嵌套 QML 组件的层次结构,并且想在内部组件中设置一些值(例如项目的颜色)。

我认为我需要做的是将参数传递给下一个内部组件,然后再将这些数据的一部分转发给他们的孩子,等等,直到到达接收者。这将尊重封装的想法。

但是,我很难在 QML/JS 中实现这一点。首先,我不确定如何导出一个函数,以便可以从组件外部调用它(在属性 var 中?我试过这个但得到一个错误“脚本元素外的 JavaScript 声明”)。其次,我不确定如何为中继器中的元素调用函数。最后,也许有更直接的方法来实现这一点?

这是一个 MWE,它传达了我想要实现的目标:

文件 mwe.qml

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
            }
        }
    }
}

文件 Mwe2.qml:

import QtQuick.Layouts 1.2

RowLayout {
    spacing: 2
    // somehow export setColors... I tried var this does not work
    //property alias setColors: setColors_
    Repeater {
        id: rect
        model: 3
        ColumnLayout {
            Rectangle {
                color: 'red'
                width: 50
                height: 20
            }
            Mwe3 { id: m3}
        }
    }
    function setColors(colors) {
        // loops over repeater items, passing
        // slice of colors array to function in m3
    }
}

文件 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 = ...
}

【问题讨论】:

  • 错字:改成m2.setColors(colors);
  • 我觉得你的设计很差,你的最终目标是什么?为什么要嵌套中继器。举一个真实的例子,因为你虚构的例子很混乱。

标签: function qt qml


【解决方案1】:

这是一种方法。请注意,我将ColumnLayout 部分移动到 Mwe3.qml 中以使其成为委托的一部分——这大大简化了访问。之后就相当简单了,只需遍历中继器子代。 “mwe1.qml”保持不变(除了修复 cmets 中提到的“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));
    }
}

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];
      }
    }
}

您可能还对使用数据模型的替代方法感兴趣。我在这里发布了一个这样的例子(也使用颜色):How can I get property in gridview which is Repeater's child

【讨论】:

  • 这行得通,谢谢。然而,在我的应用程序中,ColumnLayout 必须保留在 Mwe3 中(对象更复杂,这只是一个精简的 mwe)。在这种情况下,我如何最好地访问 Mwe3?我设法索引到“孩子”或布局,但这似乎不是很便携。通过 id 访问会更容易,但我可以这样做吗?
  • @user52366 请解释/展示为什么 ColumnLayout 不是委托的一部分的用例。因为我不明白您要做什么,所以提出随机建议很难/不可能/浪费时间。至于id 属性,当引用作为模型视图代表的项目(如Repeater)时,它是无用的(并且令人困惑)——它们显然不再是唯一的,它们不能/不应该是动态的。请记住,在中继器创建它们之前,代表实际上并不存在。或者,也许我不明白你的意思。
  • 另外需要指出的是,Repeater 的 delegate 是默认属性,这意味着放置在中继器内的任何 Item 都会成为委托 - 这正是发布的 MRE 所做的。跨度>
猜你喜欢
  • 1970-01-01
  • 2012-03-19
  • 2012-07-30
  • 2012-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多