是否可以根据参数控制将哪些项目加载到QML文件中



问题在标题上。让我举一个例子来说明,假设我有两个产品,每个产品都有不同的功能;因此,我需要在主qml文件中放入不同的项目和元素。到目前为止,我已经尝试使用Q_PROPERTYvisible特性一起控制元素,以检查参数是否具有所需的值。然而,这会导致整个混乱,锚连接等变得完全不可控,因为设计也会发生微妙的变化(不是关键的变化(。

因此,简而言之,我正在寻找一种结构,它接受一个参数并相应地加载组件。

我还留下了一个我所做的例子:

在一个类中,

Q_PROPERTY(int productType READ getproductType  WRITE setproductType  NOTIFY productType Changed);

在qml中,我让用户选择他们拥有的产品:

Button {
id: id_typeSelector
text: "Type 1"
anchors.left: parent.left
anchors.top: parent.top

onClicked: {
visible: false
object.setproductType(0)
splash.timeout()
}
}

最后,在main.qml上,我确定要显示的组件:

visible: productType === 0

我认为您需要的是组件的动态加载。其中一种方法是使用装载机。以下是如何根据所选管道材质约束管道尺寸输入的示例。

  • 木管:3〃;,5〃;或7〃;直径
  • 铁管:任何直径
  • 钢管:3〃-8〃;直径
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
Page {
anchors.fill: parent
ListModel {
id: pipes
ListElement { pipeTypeName: "Wood"; productType: 0 }
ListElement { pipeTypeName: "Iron"; productType: 1 }
ListElement { pipeTypeName: "Steel"; productType: 2 }
}
Frame {
ColumnLayout {
ComboBox {
id: comboBox
model: pipes
textRole: "pipeTypeName"
property int currentProductType: pipes.get(currentIndex).productType ?? -1
}
Loader {
sourceComponent: comboBox.currentProductType === 0 && woodInputComponent
|| comboBox.currentProductType === 1 && ironInputComponent
|| comboBox.currentProductType === 2 && steelInputComponent
|| null
}
}
}
Component {
id: woodInputComponent
RowLayout {
Layout.fillWidth: true
Text { text: qsTr("Wood Pipe Width: ") }
ComboBox { model: [3, 5, 7] }
}
}
Component {
id: ironInputComponent
RowLayout {
Layout.fillWidth: true
TextField { placeholderText: qsTr("Iron Pipe Width") }
}
}
Component {
id: steelInputComponent
RowLayout {
Layout.fillWidth: true
Text { text: qsTr("Steel Pipe Width") }
RangeSlider { from: 3; to: 8 }
}
}
}

你可以在线试用!

在上面的例子中,我使用了以下方式来选择动态加载组件,即

Loader {
sourceComponent: comboBox.currentProductType === 0 && woodInputComponent
|| comboBox.currentProductType === 1 && ironInputComponent
|| comboBox.currentProductType === 2 && steelInputComponent
|| null
}

如果您的组件在其自己的QML中声明,例如WoodInput.qmlIronInput.qmlSteelInput.qml,我们可以考虑将代码重构为更短的代码,例如

Loader {
source: pipeTypeName + "Input.qml"
}

下面是一个更扩展的示例,它使用StackView而不是Loader来演示在可以设置PipeType和PipeLength的页面之间的切换。根据所选的管道类型使用不同的管道长度编辑器:

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
Page {
anchors.fill: parent
property int purchaseIndex: -1
property var purchase: purchaseIndex >= 0 ? purchases.get(purchaseIndex) : null
ListModel {
id: purchases
}
StackView {
id: stackView
anchors.fill: parent
initialItem: gallery
}
Component {
id: gallery
Page {
header: Text {
text: qsTr("Gallery (%1 records)").arg(purchases.count)
}
ListView {
anchors.fill: parent
model: purchases
delegate: Frame {
width: ListView.view.width
RowLayout {
width: parent.width
Text {
Layout.fillWidth: true
text: model.index + " " + pipeType + " " + pipeLength
}
Button {
text: qsTr("Edit")
onClicked: {
purchaseIndex = model.index;
stackView.push(edit);
}
}
Button {
text: qsTr("Delete")
onClicked: purchases.remove(model.index)
}
}
}
}
footer: Button {
text: qsTr("New")
onClicked: newPurchase()
}
}
}
Component {
id: edit
Page {
header: Text {
text: qsTr("Edit #%1").arg(purchaseIndex)
}
ColumnLayout {
Text {
text: qsTr("PipeType: %1").arg(purchase.pipeType)
}
Text {
text: qsTr("PipeLength: %1").arg(purchase.pipeLength)
}
Button {
text: qsTr("Change Pipe Type")
onClicked: stackView.push(changePipeType)
}
Button {
text: qsTr("Change Pipe Length")
onClicked: {
let pipeType = purchases.get(purchaseIndex).pipeType;
stackView.push(
pipeType === "Wood" && changePipeLengthWood
|| pipeType === "Iron" && changePipeLengthIron
|| pipeType === "Steel" && changePipeLengthSteel
);
}
}
}
footer: Button {
text: qsTr("Done"); onClicked: stackView.pop()
}
}
}
Component {
id: changePipeType
Page {
header: Text {
text: qsTr("Change PipeType #%1").arg(purchaseIndex)
}
footer: Button {
text: qsTr("Done"); onClicked: stackView.pop()
}
ComboBox {
model: ["Wood", "Iron", "Steel"]
onCurrentTextChanged: {
purchases.setProperty(purchaseIndex, "pipeType", currentText)
}
}
}
}
Component {
id: changePipeLengthWood
Page {
header: Text {
text: qsTr("Wood Pipe Length #%1").arg(purchaseIndex)
}
Frame {
width: parent.width
ComboBox {
model: [3, 5, 7]
onCurrentTextChanged: {
try {
let pipeLength = parseInt(currentText);
purchases.setProperty(purchaseIndex, "pipeLength", pipeLength);
} catch (err) {
console.error(err.message);
}
}
}
}
footer: Button {
text: qsTr("Done"); onClicked: stackView.pop()
}
}
}
Component {
id: changePipeLengthIron
Page {
header: Text {
text: qsTr("Steel Pipe Length #%1").arg(purchaseIndex)
}
TextField {
width: parent.width
text: purchases.get(purchaseIndex).pipeLength
onTextChanged: {
purchases.setProperty(purchaseIndex, "pipeLength", parseInt(text));
}
}
footer: Button {
text: qsTr("Done"); onClicked: stackView.pop()
}
}
}
Component {
id: changePipeLengthSteel
Page {
header: Text {
text: qsTr("Steel Pipe Length #%1").arg(purchaseIndex)
}
Slider {
from: 3
to: 8
stepSize: 0.1
value: purchases.get(purchaseIndex).pipeLength
onValueChanged: {
purchases.setProperty(purchaseIndex, "pipeLength", value);
}
}
footer: Button {
text: qsTr("Done"); onClicked: stackView.pop()
}
}
}
function newPurchase() {
let purchase = {
pipeType: "Wood",
pipeLength: 3.0
};
purchases.append(purchase);
purchaseIndex = purchases.count - 1;
stackView.push(edit);
}
}

您可以在线试用此版本!

相关内容

最新更新