Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
resources.qdoc
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3/*!
4\page qtqml-javascript-resources.html
5\title Defining JavaScript Resources in QML
6\brief Description of how JavaScript files may be defined for use in QML
7
8The program logic for a QML application may be defined in JavaScript. The
9JavaScript code may either be defined in-line in QML documents, or separated
10into JavaScript files (known as \c {JavaScript Resources} in QML).
11
12There are two different kinds of JavaScript resources which are supported in
13QML: code-behind implementation files, and shared (library) files. Both kinds
14of JavaScript resource may be \l{qtqml-javascript-imports.html}{imported} by
15other JavaScript resources, or included in \l{qtqml-modules-topic.html}
16{QML modules}.
17
18\section1 Code-Behind Implementation Resource
19
20Most JavaScript files imported into a QML document are stateful implementations
21for the QML document importing them. In these cases, each instance of the QML
22object type defined in the document requires a separate copy of the JavaScript
23objects and state in order to behave correctly.
24
25The default behavior when importing JavaScript files is to provide a unique,
26isolated copy for each QML component instance. If that JavaScript file does
27not import any resources or modules with a \c{.import} statement, its code will
28run in the same scope as the QML component instance and consequently can access
29and manipulate the objects and properties declared in that QML component.
30Otherwise, it will have its own unique scope, and objects and properties of the
31QML component should be passed to the functions of the JavaScript file as
32parameters if they are required.
33
34An example of a code-behind implementation resource follows:
35
36\code
37// MyButton.qml
38import QtQuick 2.0
39import "my_button_impl.js" as Logic // A new instance of this JavaScript resource
40 // is loaded for each instance of Button.qml.
41
42Rectangle {
43 id: rect
44 width: 200
45 height: 100
46 color: "red"
47
48 MouseArea {
49 id: mousearea
50 anchors.fill: parent
51 onClicked: Logic.onClicked(rect)
52 }
53}
54\endcode
55
56\code
57// my_button_impl.js
58var clickCount = 0; // this state is separate for each instance of MyButton
59function onClicked(button) {
60 clickCount += 1;
61 if ((clickCount % 5) == 0) {
62 button.color = Qt.rgba(1,0,0,1);
63 } else {
64 button.color = Qt.rgba(0,1,0,1);
65 }
66}
67\endcode
68
69In general, simple logic should be defined in-line in the QML file, but more
70complex logic should be separated into code-behind implementation resources
71for maintainability and readability.
72
73\section1 Shared JavaScript Resources (Libraries)
74
75By default, JavaScript files imported from QML share their context with the QML
76component. That means the JavaScript files have access to the same QML objects
77and can modify them. As a consequence, each import must have a unique copy of
78these files.
79
80\l {Defining JavaScript Resources in QML#Code-Behind Implementation Resource}
81{The previous section} covers stateful imports of JavaScript files. However,
82some JavaScript files are stateless and act more like reusable libraries, in
83the sense that they provide a set of helper functions that do not require
84anything from where they were imported from. You can save significant amounts
85of memory and speed up the instantiation of QML components if you mark such
86libraries with a special pragma, as shown in the following example.
87
88\code
89// factorial.js
90.pragma library
91
92var factorialCount = 0;
93
94function factorial(a) {
95 a = parseInt(a);
96
97 // factorial recursion
98 if (a > 0)
99 return a * factorial(a - 1);
100
101 // shared state
102 factorialCount += 1;
103
104 // recursion base-case.
105 return 1;
106}
107
108function factorialCallCount() {
109 return factorialCount;
110}
111\endcode
112
113The pragma declaration must appear before any JavaScript code excluding comments.
114
115Note that multiple QML documents can import \c{"factorial.js"} and call the
116factorial and factorialCallCount functions that it provides. The state of the
117JavaScript import is shared across the QML documents which import it, and thus
118the return value of the factorialCallCount function may be non-zero when called
119within a QML document which never calls the factorial function.
120
121For example:
122
123\code
124// Calculator.qml
125import QtQuick 2.0
126import "factorial.js" as FactorialCalculator // This JavaScript resource is only
127 // ever loaded once by the engine,
128 // even if multiple instances of
129 // Calculator.qml are created.
130
131Text {
132 width: 500
133 height: 100
134 property int input: 17
135 text: "The factorial of " + input + " is: " + FactorialCalculator.factorial(input)
136}
137\endcode
138
139As they are shared, .pragma library files cannot access QML component instance
140objects or properties directly, although QML values can be passed as function
141parameters.
142
143*/