我正在尝试在树结构中的qml组件之间进行通信 . 我有一个main.qml组件,其id和root . 它有两个孩子,每个孩子都有一个从转发器和模型动态创建的任意数量的孩子 .
当点击其中一个孙子时,我希望其他人知道,并能够采取行动 . 所以,如果我可以在孙子孙女之间发送信号,那就没事了 .
问题是它们都没有设置它们的id属性,因为它们是动态制作的,而且它们中的一些属于不同的范围 . 为了在它们之间进行通信,我已经完成了以下操作:在root中创建了一个函数,每个孙都可以看到它,并且可以使用消息作为参数来调用它 . 然后,根函数以消息作为参数发出信号 . 所有的孙子都可以连接到信号,因为他们知道root的id .
人们怎么看?我感觉我已经错过了qml中的信号点,感觉就像我已经实现了一个粗略的系统并且错过了整点或者什么 .
此外,我想要远离C世界,但人们认为最好使用C类,以便我可以使用信号和插槽 .
我的目标是具有非常松散耦合的MVC结构和集中式控制器 . 人们对MVC中QML组件之间的通信有何看法 .
我在这里找到的唯一类似的问题是关于C或在组件上使用硬编码的id .
我认为id不能动态设置,甚至不能在创建时设置;我错了吗?
此外,组件在不同的范围内,因此无法解析id;我错了吗?
我写了一些代码:
//qml.main
import QtQuick 2.4
import QtQuick.Controls 1.3
ApplicationWindow {
id: root
visible: true
menuBar: MenuBar {
Menu {
title: qsTr("File")
MenuItem {
text: qsTr("&Open")
onTriggered: console.log("Open action triggered");
}
MenuItem {
text: qsTr("Exit")
onTriggered: Qt.quit();
}
}
}
property string thisName: "root"
signal rootSays(string broadcastMessage)
function callRoot(message) {
var response = message
print("Root received: " + message)
print("Root broadcasting: " + response)
rootSays(response)
}
MajorComponent{//this is root's child A
property string thisName: "A"
thisModel: [{name:"First Grandchild of A", color:"red", y:0},
{name:"Second Grandchild of A", color:"green", y:80}]
}
MajorComponent{//this is root's child B
property string thisName: "B"
thisModel: [{name:"First Grandchild of B", color:"blue", y:210},
{name:"Second Grandchild of B", color:"yellow", y:290}]
}
}
//qml.MinorComponent
import QtQuick 2.0
Rectangle {
property string thisName: ""
property string thisColor: ""
color: thisColor
height: 50; width: 200
Text {
anchors.centerIn: parent
text: thisName
}
MouseArea {
anchors.fill: parent
onClicked: {
print(thisName + " clicked")
print("Root called with: " + thisName)
root.callRoot("Hello from " + thisName)
print("---")
}
}
}
//qml.MajorComponent
import QtQuick 2.0
Rectangle {
property var thisModel: []
Repeater {
model:thisModel
MinorComponent {
y: modelData.y
thisName: modelData.name
thisColor: modelData.color
function handleResponse(response) {
print(thisName + " received: " + response);
}
Connections {
target: root
onRootSays: handleResponse(broadcastMessage)
}
}
}
}
1 回答
id
s纯粹是"compile"时间构造 . 话虽如此,没有什么可以阻止您实现和管理自己的对象注册表系统 . 一个简单的空JS对象可以做,它可以有效地用作QMap
来查找基于键(属性名称)的对象 . 如果将 Map 对象设置为根对象的属性,则应该可以从树中的每个对象解析因为动态范围 .信号的方法是一个合理的IMO . 我使用了类似的东西,结合了仿函数和通过引用捕获,允许访问任意树结构中的任意和可选现有对象,按照它们必须满足的各种标准过滤候选 . 你可以用这种技术做一些非常棘手的事情 .
话虽这么说,一个说明你实际想要实现的实际例子将有助于提供更具体的答案 .