How to communicate between components
-
Hello, I'm having trouble understanding how to pass a string between sibling components. In basic terms, there is a screen containing a menu component and a submenu component. Both menus contain their own custom buttons. Every component has a ui.qml form and a qml instantiation.
When a button is clicked in Menu I need the name of the button passed to SubMenu so that SubMenu can display buttons corresponding to that function. How do I do it? Basically MainButton.mouseArea.onClicked needs to pass a string thus:
MainButton.ui.qml -> MainButton.qml -> Menu.ui.qml -> Menu.qml -> Screen.ui.qml -> Screen.qml -> SubMenu.qml -> SubMenu.ui.qml
Maybe I should be thinking of the ui.qml and the qml as a single object, but it seems to be tricky to get the qml file event to be recognized in the ui.qml. I know I need to trigger 'something' in the onClicked that propagates the string, but is that a signal and if so where does the signal get defined? If I define it at the top in the screen object, the button cannot see it.
Below is an outline of the files I have. Thanks for the help.
Screen01.qml
Screen01Form { }
Screen01Form.ui.qml
Item { Menu { } SubMenu { } }
Menu.qml
MenuForm { }
MenuForm.ui.qml
Item { MenuButton { btnName: "Button 1" } MenuButton { btnName: "Button 2" } MenuButton { btnName: "Button 3" } }
SubMenu.qml
SubMenuForm { }
SubMenuForm.ui.qml
Item { }
MenuButton.qml
MenuButtonForm { btnMouseArea.onClicked: { - call a signal? } }
MenuButtonForm.ui.qml
Rectangle { property alias btnMouseArea: btnMouseArea MouseArea { id: btnMouseArea anchors.fill: parent } }
-
Use signals & connections to pass the information.
Refer https://doc.qt.io/qt-6/qtqml-syntax-signals.html -
Yes I have been trying to use signals. But I think my problem is with scope. I put the signal in Menu but it is not received by Screen. In the abberviated code below, HERE1 gets output but HERE2 does not.
Menu.qml
Item { property string selectedName: "" signal menuChanged(string newName) onSelectedNameChanged: { menuChanged(name) console.log("HERE1") } }
ScreenForm.ui.qml
Rectangle { property alias menuComponent: menu Menu { id: menu } Submenu { id: submenu } }
Screen.qml
ScreenForm { Connections { target: menuComponent function onMenuChanged(newName) { console.log("HERE2") } } }
Even if I put an intermediary signal in ScreenForm, I cannot receive it in Screen and I'm not sure why it's not working. In the below example I put a signal 'formMenuChanged' in ScreenForm but only HERE1 and HERE2 get printed and HERE3 does not.
Menu.qml
Item { property string selectedName: "" signal menuChanged(string newName) onSelectedNameChanged: { menuChanged(name) console.log("HERE1") } }
ScreenForm.ui.qml
Rectangle { property alias menuComponent: menu signal formMenuChanged(string newName) Menu { id: menu Connections { function onMenuChanged(newName) { console.log("HERE2") formMenuChanged(newName) } } } Submenu { id: submenu } }
Screen.qml
ScreenForm { Connections { function onFormMenuChanged(newName) { console.log("HERE3") } } }
-
Make the topic as "Solved" as well.