[SOLVED] include stateless js files



  • Hello.

    What do you think this program shows?
    Is it good that file with .pragma library becomes statefull?

    @//main.qml
    import QtQuick 1.1
    import "stateless.js" as A
    import "statefull.js" as B

    Text {
    id: text
    Component.onCompleted: {
    A.x = 1;
    B.x = 2;
    text.text = "A.x = " + A.x + "; B.x = " + B.x
    }
    }@

    @//statefull.js
    Qt.include("stateless.js")@

    @//stateless.js
    .pragma library

    var x@



  • Hi.

    The documentation about .pragma library scripts is plain wrong.
    .pragma library scripts are not stateless - they just have a single state which is shared across all imports.

    Note that doing Qt.include() does NOT import a script - instead, it copy-and-pastes the script contents into the current script's evaluation context and evaluates it. Only an 'import "someScript.js" as SomeQualifier' statement in a QML file, or a '.import "someScript.js" as SomeQualifier' statement in a JS file (qtquick2 only), are true "import statements" -- ie, which observe imports / pragmas defined.

    ALL javascript imports are stateful. It's just that some are shared state (pragma library scripts) and some are per-import state (non-pragma library scripts).

    Here's an example:

    @
    // test.qml
    import QtQuick 2.0

    Rectangle {
    id: root
    width: 400
    height: 400

    Comp1 {
        id: c1
        anchors.top: root.top
    }
    
    Comp2 {
        id: c2
        anchors.bottom: root.bottom
    }
    

    }

    // Comp1.qml
    import QtQuick 2.0
    import "js1.js" as A
    import "js2.js" as B

    Text {
    id: text1
    Component.onCompleted: {
    A.x = A.x + 1;
    B.x = B.x + 2;
    text1.text = "A.x = " + A.x + "; B.x = " + B.x
    }
    }

    // Comp2.qml
    import QtQuick 2.0
    import "js1.js" as A
    import "js2.js" as B

    Text {
    id: text2
    Component.onCompleted: {
    A.x = A.x + 1;
    B.x = B.x + 2;
    text2.text = "A.x = " + A.x + "; B.x = " + B.x
    }
    }

    // js1.js
    Qt.include("js2.js")

    // js2.js
    .pragma library
    var x = 1
    @

    We expect the output to display either:

    A.x = 2; B.x = 3
    A.x = 2; B.x = 5

    OR

    A.x = 2; B.x = 5
    A.x = 2; B.x = 3

    depending on the order with which the component onCompleted handlers are invoked.
    In fact, with QtQuick2, currently the second one is what we see (but that's basically arbitrary).
    The important point is that A.x in both will equal 2 (the state of the "js1.js" import is NOT shared because it's not a pragma library, while the state of the "js2.js" import IS shared because it is.)

    Cheers,
    Chris.



  • Thank you very much.

    So is it impossible (in QtQuick 1.1) to have global variables for all of my project? Is library with shared state accessible only from qml files but not from js files?

    I already did a workaround for this but it is not very beautiful.



  • It's difficult in QtQuick1.x but not impossible. You can, for example, use a single .pragma library script as the single repository of shared global data, and then import it from all QML files where you need it.
    For those non-pragma-library JavaScript files which need to access that data, you'll have to pass the data to them as function arguments, rather than attempting to access it directly (since in QtQuick 1.x there is no way to import one JavaScript file from another; that is a QtQuick2 feature, as are module apis).

    Cheers,
    Chris.


Log in to reply
 

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