1

I have the following qml files, the main.qml creates TestWindow.qml elements.

I would like to connect a signal in TestWindow.qml (click on a button mySignalToMainWindow() ) to a function in main.qml, testConnection().

main.qml

Window {
    id: _component

    property int instances: 3

    width: 200
    height: Screen.height / 2
    visible: true

    Component.onCompleted: {
        x = 40
        y = 40
    }

    Repeater {
        id: _windows
        model: instances
        TestWindow {
            index: model.index
            leftOffset: _component.width
        }
    }

    Column {
        Repeater {
            model: instances
            Button {
                text: "Window " + index
                onClicked:{ _windows.itemAt(index).window.raise();
                }
            }
        }
    }

    function testConnection(){console.log("Subwindow To Main Window")}
}

And TestWindow.qml :

Item {
    id: _windowItem
    property int index
    property int leftOffset
    property alias window: _window
    signal mySignalToMainWindow()

    Window {
        id: _window

        visible: true
        title: "SubWindowText " + index

        Component.onCompleted: {
            x = leftOffset
            y = 40
            width = Screen.width - leftOffset
            height = Screen.height / 2
        }

        Text {
            id: windowText
            text: qsTr("SubWindowText")
        }

        Button {
            text: "SubWindow " + index
            onClicked: {console.log("TestWindow::Button onClicked "+_window);
                _windowItem.mySignalToMainWindow();
            }
        }
    }

}

I tested those two :

How to bind to a signal from a delegate component within a ListView in QML and How to access dynamically/randomly loaded Repeater items in QML?

with no success. So, how to do that?

Thanks

Community
  • 1
  • 1
SteveTJS
  • 635
  • 17
  • 32

1 Answers1

3

You have multiple options there. The first is to define the binding, when creating the Component for the delegate:

Repeater {
    id: _windows
    model: instances
    TestWindow {
        index: model.index
        leftOffset: _component.width
        onMySignalToMainWindow: testConnection() <--- Here you can connect it.
    }
}

Another option is to use the onItemAdded and onItemRemoved-Handlers and connect the function there (mySignalToMainWindow.connect(functionToConnect)) and the respective disconnect, when it gets destroyed.

I'd recommend the former, if you want the connection to be permanent, and the latter if you might want to disconnect at some time.

The onItemAdded/onRemoved handlers are especially important if you don't declare a delegate for the Repeater. This happens for example if you use a DelegateModel or an ObjectModel. As with those models, you can't be sure, the objects are instantiated or destroyed when the Repeater adds or removes them, you could not use the often mentioned: Component.onCompleted/onDestruction, so I consider the itemAdded/Removed-signals superior/more general for the use with a Repeater.

BaCaRoZzo
  • 7,502
  • 6
  • 51
  • 82