Many signals one slot



  • I have a collection of QML objects (I've defined the same custom type for all of them). I want them all to notify the same instance of parent object upon a user click. What's the easiest way I can achieve this? Will I need to implement a connection for each instantiated item of my type?



  • Hi,
    https://doc.qt.io/archives/qq/qq10-signalmapper.html
    Here you have :

    The Trivial Solution
    The sender() Approach
    The Subclass Approach
    The Signal Mapper Approach

    LA



  • This post is deleted!


  • @LeLev I'm looking for a purely QML solution. I'm designing a settings menu and toggling enabled/disabled on panels based on the selection of other menu items.



  • @corruptedsyntax I can't quite grasp your explanation but maybe something like this:

    import QtQuick 2.6
    import QtQuick.Layouts 1.3
    import QtQuick.Controls 2.1
    
    ApplicationWindow {
        id: window
        width: 360
        height: 520
        visible: true
        Item {
            function onButtonClicked(num_button){
                console.log(num_button)
            }
            ColumnLayout {
                Button {
                    text: "1"
                    onClicked: parent.parent.onButtonClicked(text)
                }
                Button {
                    text: "2"
                    onClicked: parent.parent.onButtonClicked(text)
                }
            }
        }
    }
    

    where the Button is promoted to your custom component. 'parent' inside a component file should be automatically resolved during runtime. Or you can add the listening object as a property to your component.



  • I have a custom type for a collapsible menu item containing a label and collapsible panel for a setting. The respective data item panel is toggled visible/invisible based on the user clicking the label item. Only 1 data item may be shown at a time, so my design is:

    1. User clicks label panel to enable data panel and make it visible
    2. All data panels are disabled and made invisible
    3. Selected data panel is made visible and enabled

    Step 3 is achieved easily by defining by defining a single signal handler inside my custom type which listens to its parent. However step 2 requires that the parent object listens for signals from ALL children. I may be scaling the number of menu item children objects I am instancing as time goes on, and this will cause a lot of copy/paste code if there's not a better way to manage this. Example of how it's being done now:

    //Custom type DoublePanel.qml
    Rectangle {
        signal enableBox();
        Rectangle {
            id: leftLabel
            ...
            MouseArea {
                ...
                onClicked: {
                    enableBox();
                    //code to enable this box after signal to disable all boxes
                    ...
                }
            }
        }
        Rectangle {
            id: rightData
            ...
        }
        Connections {
            target: parent.parent
            onDisableAll: {
                //code to disable here
                ...
            }
        }
    }
    
    //User context, CollapsibleBar.qml
    Rectangle {
        signal disableAll();
        ...
        DoublePanel {
            id: panelSetting1
            Connections {    //Is this Connections code block avoidable with each instance?
                target: panelSetting1
                onEnableBox: {
                    disableAll();
                }
            }
        }
        DoublePanel {
            id: panelSetting2
            Connections {    //Is this Connections code block avoidable with each instance?
                target: panelSetting2
                onEnableBox: {
                    disableAll();
                }
            }
        }
        DoublePanel {
            id: panelSetting3
            Connections {    //Is this Connections code block avoidable with each instance?
                target: panelSetting3
                onEnableBox: {
                    disableAll();
                }
            }
        }
        ...
    }
    


  • @corruptedsyntax First, why do you use Connections when the target is the same as the parent of that Connections? This should work:

    DoublePanel {
            id: panelSetting1
                onEnableBox: {
                    disableAll();
                }
            }
        }
    

    Second, you should be able to move it to the component and call parent.disableAll() (assuming that the Rectangle which has disableAll is the direct parent):

    //Custom type DoublePanel.qml
    Rectangle {
        onEnableBox: {
                    parent.disableAll();
                }
    ...
    

    (Though I haven't tested this.)



  • @Eeli-K Only been using QML about a week and I've been on a tight timeline. So far it's just been throwing stuff together to make it work. Got a few days to spare, so now it's worth refactoring. Thanks for the tips, I thought I might be considerably over complicating things



  • @corruptedsyntax Then you've got a good start.

    'Connections' is for writing a signal handler in other component than the sender - in C++ a signal and a slot are connected with connect(), in QML all senders can have corresponding onX handlers and any component can handle a signal from any available sender object with Connections.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.