ohporter
ohporter

Reputation: 23

Refactoring QML and keeping components in scope

I have a larger QML project that I'm trying to refactor so that some related components are in their own file. In my simplified example, what is part of ThingManager.qml was previously simply included in the main.qml file. Prior to refactoring, the scope of ids, a, b, and c were visible to page.qml since they were defined in the main file. As I tried to abstract these into a ThingManager component to reduce clutter in my main.qml, page.qml was no longer able to reference those with the familar scoping error:

page.qml:9: ReferenceError: a is not defined

Given that I am loading pages similar to page.qml and want to execute methods within these components stored in another file, what is the recommended way to refactor something like this example such that page.qml can access methods in these components without them being defined in main.qml? Or is that simply not possible to do?

main.qml:

import QtQuick 2.7
import QtQuick.Controls 2.1
import QtQml 2.2

ApplicationWindow {
    id: window

    ThingManager { }

    Loader {
            id: page_loader
    }

    Component.onCompleted: {
            page_loader.setSource("page.qml")
    }
}

ThingManager.qml:

import QtQuick 2.7
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.3

Item {
    Column {
            Button {
                    id: a
                    text: "A"
            }
            Button {
                    id: b
                    text: "B"
            }
            Button {
                    id: c
                    text: "C"
            }
    }
}

page.qml:

import QtQuick 2.7
import QtQuick.Controls 2.1

Page {
        id: page

        Component.onCompleted: {
                console.log("Execute A's method")
                a.toggle()
        }
}

Upvotes: 1

Views: 309

Answers (1)

m7913d
m7913d

Reputation: 11064

You should add an id to ThingManager and define a as an alias property in ThingManager.qml as follows:

main.qml:

...
ThingManager {id: manager }
...

ThingManager.qml:

Item {
    property alias a: a // makes 'a' available outside this file
    property alias b: b
    property alias c: c

    ...
}

page.qml:

...
manager.a.toggle ()
...

Upvotes: 1

Related Questions