I'm trying to communicate between qml components in a tree structure. I have a main.qml component with and id of root. It has two children, and each of those children has an arbitrary number of children dynamically created from a repeater and a model.
When one of the grandchildren is clicked I would like the others to know, and be able to take action. So if I could send signals between the grandchildren that would be fine.
The problem is none of them have their id property set because they are made dynamically, and some of them are in different scopes. To communicate between them I have done the following: Created a function in root, every grandchild can see that, and can call it with a message as parameter. The root function then emits a signal with the message as parameter. All the grandchildren can connect to the signal because they know the id of root.
What do people think of that? I'm getting the feeling that I've missed the point of signals in qml, feels like i've implemented a crude system and missed the whole point or something.
Also, I want to stay out of the C++ world, but do people think it would be best to use a C++ class so that I can use signals and slots.
What I'm aiming at is an MVC structure with very loose coupling, and a centralised Controller. What do people think about communicating between QML components in MVC.
The only similar questions I found here were about C++ or using hard-coded id's on components.
I don't think id's can be set dynamically, not even once at creation; am I wrong about that?
Also, the components are in different scopes, so id's can't be resolved; am I wrong about that?
I've written some code:
//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)
}
}
}
}
pragma Singleton
in QML) – peppe