aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Adams <christopher.adams@nokia.com>2012-07-06 16:02:46 +1000
committerQt by Nokia <qt-info@nokia.com>2012-07-11 02:59:48 +0200
commit7ee8156116581e08466ebc23b31e2b76c127e742 (patch)
treee73aea79b344f023dd1e9242f5da4f4b45a42ecf
parenta1a2c81d7fd5512b8c0531b01453656fc4c96bed (diff)
Improve documentation for JavaScript expressions and imports
This commit splits the import documentation out of the expression documentation, and corrects various ambiguities or errors in the JavaScript-related documentation. Change-Id: I351b0676f7271efba7cbff90c133dfe008321fb8 Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
-rw-r--r--src/qml/doc/src/javascript/dynamicobjectcreation.qdoc230
-rw-r--r--src/qml/doc/src/javascript/dynamicobjectcreation.qodc211
-rw-r--r--src/qml/doc/src/javascript/expressions.qdoc439
-rw-r--r--src/qml/doc/src/javascript/hostenvironment.qdoc2
-rw-r--r--src/qml/doc/src/javascript/imports.qdoc155
5 files changed, 585 insertions, 452 deletions
diff --git a/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc b/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc
new file mode 100644
index 0000000000..bd8e50cd53
--- /dev/null
+++ b/src/qml/doc/src/javascript/dynamicobjectcreation.qdoc
@@ -0,0 +1,230 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms
+** and conditions contained in a signed written agreement between you
+** and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+\page qtqml-javascript-dynamicobjectcreation.html
+\title Dynamic QML object creation from JavaScript
+\brief instantiating and managing QML objects from JavaScript
+
+QML supports the dynamic creation of objects from within JavaScript. This is
+useful to delay instantiation of objects until necessary, thereby improving
+application startup time. It also allows visual objects to be dynamically
+created and added to the scene in reaction to user input or other events.
+
+See the \l {declarative/toys/dynamicscene}{Dynamic Scene example} for a
+demonstration of the concepts discussed on this page.
+
+
+\section1 Creating Objects Dynamically
+
+There are two ways to create objects dynamically from JavaScript. You can
+either call \l {QML:Qt::createComponent()}{Qt.createComponent()} to
+dynamically create a \l Component object, or use \l{QML:Qt::createQmlObject()}
+{Qt.createQmlObject()} to create an object from a string of QML. Creating a
+component is better if you have an existing component defined in a QML document
+and you want to dynamically create instances of that component. Otherwise,
+creating an object from a string of QML is useful when the object QML itself is
+generated at runtime.
+
+
+\section2 Creating a Component Dynamically
+
+To dynamically load a component defined in a QML file, call the
+\l {QML:Qt::createComponent()}{Qt.createComponent()} function in the
+\l {QmlGlobalQtObject}{Qt object}.
+This function takes the URL of the QML file as its only argument and creates
+a \l Component object from this URL.
+
+Once you have a \l Component, you can call its \l {Component::createObject()}
+{createObject()} method to create an instance of the component. This function
+can take one or two arguments:
+\list
+\li The first is the parent for the new object. The parent can be a graphical
+ object (QtQuick item) or non-graphical object (QtQml QtObject or C++
+ QObject). Only graphical objects with graphical parent objects will be
+ rendered to the QtQuick visual canvas. If you wish to set the parent later
+ you can safely pass \c null to this function.
+\li The second is optional and is a map of property-value pairs that define
+ initial any property values for the object. Property values specified by
+ this argument are applied to the object before its creation is finalized,
+ avoiding binding errors that may occur if particular properties must be
+ initialized to enable other property bindings. Additionally, there are
+ small performance benefits when compared to defining property values and
+ bindings after the object is created.
+\endlist
+
+Here is an example. First there is \c Sprite.qml, which defines a simple QML component:
+
+\snippet qml/Sprite.qml 0
+
+Our main application file, \c main.qml, imports a \c componentCreation.js
+JavaScript file that will create \c Sprite objects:
+
+\snippet qml/createComponent.qml 0
+
+Here is \c componentCreation.js. Notice it checks whether the component
+\l{Component::status}{status} is \c Component.Ready before calling
+\l {Component::createObject()}{createObject()} in case the QML file is loaded
+over a network and thus is not ready immediately.
+
+\snippet qml/componentCreation.js vars
+\codeline
+\snippet qml/componentCreation.js func
+\snippet qml/componentCreation.js remote
+\snippet qml/componentCreation.js func-end
+\codeline
+\snippet qml/componentCreation.js finishCreation
+
+If you are certain the QML file to be loaded is a local file, you could omit
+the \c finishCreation() function and call \l {Component::createObject()}
+{createObject()} immediately:
+
+\snippet qml/componentCreation.js func
+\snippet qml/componentCreation.js local
+\snippet qml/componentCreation.js func-end
+
+Notice in both instances, \l {Component::createObject()}{createObject()} is
+called with \c appWindow passed as the parent argument, since the dynamically
+created object is a visual (QtQuick) object. The created object will become a
+child of the \c appWindow object in \c main.qml, and appear in the scene.
+
+When using files with relative paths, the path should
+be relative to the file where \l {QML:Qt::createComponent()}
+{Qt.createComponent()} is executed.
+
+To connect signals to (or receive signals from) dynamically created objects,
+use the signal \c connect() method. See
+\l{Signal and Handler Event System#Connecting Signals to Methods and Signals}
+{Connecting Signals to Methods and Signals} for more information.
+
+It is also possible to instantiate components without blocking via the
+\l {Component::incubateObject()}{incubateObject()} function.
+
+\section2 Creating an Object from a String of QML
+
+If the QML is not defined until runtime, you can create a QML object from
+a string of QML using the \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}
+function, as in the following example:
+
+\snippet qml/createQmlObject.qml 0
+
+The first argument is the string of QML to create. Just like in a new file,
+you will need to import any types you wish to use. The second argument is the
+parent object for the new object, and the parent argument semantics which apply
+to components are similarly applicable for \c createQmlObject().
+The third argument is the file path to associate with the new object; this is
+used for error reporting.
+
+If the string of QML imports files using relative paths, the path should be
+relative to the file in which the parent object (the second argument to the
+method) is defined.
+
+
+\section1 Maintaining Dynamically Created Objects
+
+When managing dynamically created objects, you must ensure the creation context
+outlives the created object. Otherwise, if the creation context is destroyed
+first, the bindings in the dynamic object will no longer work.
+
+The actual creation context depends on how an object is created:
+
+\list
+\li If \l {QML:Qt::createComponent()}{Qt.createComponent()} is used, the
+ creation context is the QQmlContext in which this method is called
+\li If \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()} is called, the
+ creation context is the context of the parent object passed to this method
+\li If a \c {Component{}} object is defined and \l {Component::createObject()}
+ {createObject()} or \l {Component::incubateObject()}{incubateObject()} is
+ called on that object, the creation context is the context in which the
+ \c Component is defined
+\endlist
+
+Also, note that while dynamically created objects may be used the same as other
+objects, they do not have an id in QML.
+
+
+\section1 Deleting Objects Dynamically
+
+In many user interfaces, it is sufficient to set a visual object's opacity to 0
+or to move the visual object off the screen instead of deleting it. If you have
+lots of dynamically created objects, however, you may receive a worthwhile
+performance benefit if unused objects are deleted.
+
+Note that you should never manually delete objects that were dynamically
+created by convenience QML object factories (such as \l Loader and
+\l Repeater). Also, you should avoid deleting objects that you did not
+dynamically create yourself.
+
+Items can be deleted using the \c destroy() method. This method has an optional
+argument (which defaults to 0) that specifies the approximate delay in
+milliseconds before the object is to be destroyed.
+
+Here is an example. The \c application.qml creates five instances of the
+\c SelfDestroyingRect.qml component. Each instance runs a NumberAnimation,
+and when the animation has finished, calls \c destroy() on its root object to
+destroy itself:
+
+\table
+\row
+\li \c application.qml
+\li \c SelfDestroyingRect.qml
+
+\row
+\li \snippet qml/dynamicObjects-destroy.qml 0
+\li \snippet qml/SelfDestroyingRect.qml 0
+
+\endtable
+
+Alternatively, the \c application.qml could have destroyed the created object
+by calling \c object.destroy().
+
+Note that it is safe to call destroy() on an object within that object. Objects
+are not destroyed the instant destroy() is called, but are cleaned up sometime
+between the end of that script block and the next frame (unless you specified a
+non-zero delay).
+
+Note also that if a \c SelfDestroyingRect instance was created statically like
+this:
+
+\qml
+Item {
+ SelfDestroyingRect {
+ // ...
+ }
+}
+\endqml
+
+This would result in an error, since objects can only be dynamically
+destroyed if they were dynamically created.
+
+Objects created with \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}
+can similarly be destroyed using \c destroy():
+
+\snippet qml/createQmlObject.qml 0
+\snippet qml/createQmlObject.qml destroy
+
+*/
diff --git a/src/qml/doc/src/javascript/dynamicobjectcreation.qodc b/src/qml/doc/src/javascript/dynamicobjectcreation.qodc
deleted file mode 100644
index 424426322a..0000000000
--- a/src/qml/doc/src/javascript/dynamicobjectcreation.qodc
+++ /dev/null
@@ -1,211 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:FDL$
-** GNU Free Documentation License
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms
-** and conditions contained in a signed written agreement between you
-** and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/*!
-\page qtqml-javascript-dynamicobjectcreation.html
-\title Dynamic QML object creation from JavaScript
-\brief instantiating and managing QML objects from JavaScript
-
-QML also supports the dynamic creation of objects from within JavaScript
-code. This is useful if the existing QML elements do not fit the needs of your
-application, and there are no C++ components involved.
-
-See the \l {declarative/toys/dynamicscene}{Dynamic Scene example} for a demonstration
-of the concepts discussed on this page.
-
-
-\section1 Creating Objects Dynamically
-
-There are two ways to create objects dynamically from JavaScript. You can either call
-\l {QML:Qt::createComponent()}{Qt.createComponent()} to dynamically create
-a \l Component object, or use \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}
-to create an item from a string of QML.
-Creating a component is better if you have an existing component defined in a \c .qml
-file, and you want to dynamically create instances of that component. Otherwise,
-creating an item from a string of QML is useful when the item QML itself is generated
-at runtime.
-
-
-\section2 Creating a Component Dynamically
-
-To dynamically load a component defined in a QML file, call the
-\l {QML:Qt::createComponent()}{Qt.createComponent()} function in the
-\l {QmlGlobalQtObject}{Qt object}.
-This function takes the URL of the QML file as its only argument and creates
-a \l Component object from this URL.
-
-Once you have a \l Component, you can call its \l {Component::createObject()}{createObject()} method to create an instance of
-the component. This function can take one or two arguments:
-\list
-\li The first is the parent for the new item. Since graphical items will not appear on the scene without a parent, it is
- recommended that you set the parent this way. However, if you wish to set the parent later you can safely pass \c null to
- this function.
-\li The second is optional and is a map of property-value items that define initial any property values for the item.
- Property values specified by this argument are applied to the object before its creation is finalized, avoiding
- binding errors that may occur if particular properties must be initialized to enable other property bindings.
- when certain properties have been bound to before they have been set by the code. Additionally, there are small
- performance benefits when compared to defining property values and bindings after the object is created.
-\endlist
-
-Here is an example. First there is \c Sprite.qml, which defines a simple QML component:
-
-\snippet qml/Sprite.qml 0
-
-Our main application file, \c main.qml, imports a \c componentCreation.js JavaScript file
-that will create \c Sprite objects:
-
-\snippet qml/createComponent.qml 0
-
-Here is \c componentCreation.js. Notice it checks whether the component \l{Component::status}{status} is
-\c Component.Ready before calling \l {Component::createObject()}{createObject()}
-in case the QML file is loaded over a network and thus is not ready immediately.
-
-\snippet qml/componentCreation.js vars
-\codeline
-\snippet qml/componentCreation.js func
-\snippet qml/componentCreation.js remote
-\snippet qml/componentCreation.js func-end
-\codeline
-\snippet qml/componentCreation.js finishCreation
-
-If you are certain the QML file to be loaded is a local file, you could omit the \c finishCreation()
-function and call \l {Component::createObject()}{createObject()} immediately:
-
-\snippet qml/componentCreation.js func
-\snippet qml/componentCreation.js local
-\snippet qml/componentCreation.js func-end
-
-Notice in both instances, \l {Component::createObject()}{createObject()} is called with
-\c appWindow passed as an argument so that the created object will become a child of the
-\c appWindow item in \c main.qml. Otherwise, the new item will not appear in the scene.
-
-When using files with relative paths, the path should
-be relative to the file where \l {QML:Qt::createComponent()}{Qt.createComponent()} is executed.
-
-To connect signals to (or receive signals from) dynamically created objects,
-use the signal \c connect() method. See
-\l{Signal and Handler Event System#Connecting Signals to Methods and Signals}
-{Connecting Signals to Methods and Signals} for more information.
-
-It is also possible to instantiate components without blocking via the
-\l {Component::incubateObject()}{incubateObject()} function.
-
-\section2 Creating an Object from a String of QML
-
-If the QML is not defined until runtime, you can create a QML item from
-a string of QML using the \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()} function, as in the following example:
-
-\snippet qml/createQmlObject.qml 0
-
-The first argument is the string of QML to create. Just like in a new file, you will need to
-import any types you wish to use. The second argument is the parent item for the new item;
-this should be an existing item in the scene. The third argument is the file path to associate
-with the new item; this is used for error reporting.
-
-If the string of QML imports files using relative paths, the path should be relative
-to the file in which the parent item (the second argument to the method) is defined.
-
-
-\section1 Maintaining Dynamically Created Objects
-
-When managing dynamically created items, you must ensure the creation context
-outlives the created item. Otherwise, if the creation context is destroyed first,
-the bindings in the dynamic item will no longer work.
-
-The actual creation context depends on how an item is created:
-
-\list
-\li If \l {QML:Qt::createComponent()}{Qt.createComponent()} is used, the creation context
- is the QQmlContext in which this method is called
-\li If \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}
- if called, the creation context is the context of the parent item passed to this method
-\li If a \c {Component{}} item is defined and \l {Component::createObject()}{createObject()}
- or \l {Component::incubateObject()}{incubateObject()} is called on that item,
- the creation context is the context in which the \c Component is defined
-\endlist
-
-Also, note that while dynamically created objects may be used the same as other objects, they
-do not have an id in QML.
-
-
-\section1 Deleting Objects Dynamically
-
-In many user interfaces, it is sufficient to set an item's opacity to 0 or
-to move the item off the screen instead of deleting the item. If you have
-lots of dynamically created items, however, you may receive a worthwhile
-performance benefit if unused items are deleted.
-
-Note that you should never manually delete items that were dynamically created
-by QML elements (such as \l Loader and \l Repeater). Also, you should avoid deleting
-items that you did not dynamically create yourself.
-
-Items can be deleted using the \c destroy() method. This method has an optional
-argument (which defaults to 0) that specifies the approximate delay in milliseconds
-before the object is to be destroyed.
-
-Here is an example. The \c application.qml creates five instances of the \c SelfDestroyingRect.qml
-component. Each instance runs a NumberAnimation, and when the animation has finished, calls
-\c destroy() on its root item to destroy itself:
-
-\table
-\row
-\li \c application.qml
-\li \c SelfDestroyingRect.qml
-
-\row
-\li \snippet qml/dynamicObjects-destroy.qml 0
-\li \snippet qml/SelfDestroyingRect.qml 0
-
-\endtable
-
-Alternatively, the \c application.qml could have destroyed the created object
-by calling \c object.destroy().
-
-Note that it is safe to call destroy() on an object within that object. Objects are not destroyed the
-instant destroy() is called, but are cleaned up sometime between the end of that script block and the next frame
-(unless you specified a non-zero delay).
-
-Note also that if a \c SelfDestroyingRect instance was created statically like this:
-
-\qml
-Item {
- SelfDestroyingRect {
- // ...
- }
-}
-\endqml
-
-This would result in an error, since items can only be dynamically
-destroyed if they were dynamically created.
-
-Objects created with \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}
-can similarly be destroyed using \c destroy():
-
-\snippet qml/createQmlObject.qml 0
-\snippet qml/createQmlObject.qml destroy
-
-*/
diff --git a/src/qml/doc/src/javascript/expressions.qdoc b/src/qml/doc/src/javascript/expressions.qdoc
index 73b27bd135..33007943f0 100644
--- a/src/qml/doc/src/javascript/expressions.qdoc
+++ b/src/qml/doc/src/javascript/expressions.qdoc
@@ -30,43 +30,130 @@
\brief Description of where JavaScript expressions are valid in QML documents
-\code
-
-This article is a work-in-progress.
-
-\endcode
-
-JavaScript adds logic to QML components. Properties can bind
-to JavaScript expressions or reside inline in functions or signal handlers. The
-\l{QQmlEngine}{QML engine} will then interpret the expression to calculate new
-property values or to execute a routine.
-
-The \l{JavaScript Host Environment} can run valid standard
+The \l{JavaScript Host Environment} provided by QML can run valid standard
JavaScript constructs such as conditional operators, arrays, variable setting,
loops. In addition to the standard JavaScript properties, the \l {QML Global
Object} includes a number of helper methods that simplify building UIs and
interacting with the QML environment.
The JavaScript environment provided by QML is stricter than that in a web
-browser. In QML you cannot add, or modify, members of the JavaScript global
-object. In regular JavaScript, it is possible to do this accidentally by using a
-variable without declaring it. In QML this will throw an exception, so all local
-variables should be explicitly declared.
+browser. For example, in QML you cannot add, or modify, members of the
+JavaScript global object. In regular JavaScript, it is possible to do this
+accidentally by using a variable without declaring it. In QML this will throw
+an exception, so all local variables should be explicitly declared. A complete
+description of the limitations of JavaScript code in QML is included in an
+\l{JavaScript Expression Restrictions in QML}{upcoming section}.
+
+There are various ways in which JavaScript expressions may be defined and used
+in QML, including property bindings, signal handlers, custom methods and
+JavaScript imports.
+
+
+
+
+\section1 JavaScript Expressions in QML Objects
+
+QML \l{QML Object Types}{object types} defined in \l{QML Documents}
+{QML documents} can make use of JavaScript expressions which implement program
+logic. There are four ways that JavaScript can be used in a QML document:
+
+\list
+ \li \l{QML Object Attributes#property-initialization}{properties} can be
+ assigned \l{Property Binding}{bindings} which are defined with
+ JavaScript expressions, and which are automatically evaluated by the
+ \l{QQmlEngine}{QML engine} when any properties accessed in the binding
+ change, in order to ensure always-up-to-date property values. Binding
+ expressions can also perform function evaluation as an explicit side
+ effect
+ \li \l{QML Object Attributes#signal-handlers}{signal handlers} can be defined
+ which are automatically evaluated when the object emits the associated
+ signal
+ \li \l{QML Object Attributes#custom-methods}{custom methods} can be defined
+ in QML files as JavaScript functions
+ \li JavaScript files providing functions and variables can be
+ \l{Importing JavaScript Files In QML Documents}{imported} in a QML
+ document
+\endlist
+
+
+
+\section2 Property Bindings
+
+During startup, the QML engine will set up and initialize the property
+bindings. The JavaScript conditional operator is a valid property binding.
+
+\qml
+import QtQuick 2.0
+
+Rectangle {
+ id: colorbutton
+ width: 200; height: 80;
+
+ color: mousearea.pressed ? "steelblue" : "lightsteelblue"
+
+ MouseArea {
+ id: mousearea
+ anchors.fill: parent
+ }
+}
+\endqml
+
+In fact, any JavaScript expression (no matter how complex) may be used in a
+property binding definition, as long as the result of the expression is a
+value whose type can be assigned to the property.
+
+There are two ways to define a property binding: the first (and most common)
+is, as previously shown, in a \l{QML Object Attributes#property-initialization}
+{property initialization}. The second (and much rarer) way is to assign the
+property a function returned from the \l{Qt::binding()}{Qt.binding()} function,
+from within imperative JavaScript code, as shown below:
+
+\qml
+import QtQuick 2.0
+
+Rectangle {
+ id: colorbutton
+ width: 200; height: 80;
+ color: "red"
+
+ MouseArea {
+ id: mousearea
+ anchors.fill: parent
+ }
+
+ Component.onCompleted: {
+ color = Qt.binding(function() { return mousearea.pressed ? "steelblue" : "lightsteelblue" });
+ }
+}
+\endqml
-\section1 Adding Logic
+See the \l{Property Binding}{property bindings} documentation for more
+information about how to define property bindings, and see the documentation
+about \l{qml-javascript-assignment}
+{Property Assignment versus Property Binding} for information about how
+bindings differ from value assignments.
-The \l {QML Elements} provide a declarative way of creating and managing the
-interface layout and scene. Binding properties or signal handlers to JavaScript
-expressions adds logic to the QML application.
+
+
+\section2 Signal Handlers
+
+QML object types can emit signals in reaction to certain events occurring.
+Those signals can be handled by signal handler functions, which can be defined
+by clients to implement custom program logic.
Suppose that a button represented by a Rectangle element has a MouseArea and a
-Text label. The MouseArea will call its \l{MouseArea::}{onPressed} handler when the user presses the defined interactive area. The QML engine will execute the
-contents bound to the onPressed and onReleased handlers. Typically, a signal
-handler is bound to JavaScript expressions to initiate other events or to simply
-assign property values.
+Text label. The MouseArea will emit its "pressed" signal when the user presses
+the defined interactive area, which will automatically trigger the
+\l{MouseArea::}{onPressed} handler, which can be defined by clients. The QML
+engine will execute the JavaScript expressions defined in the onPressed and
+onReleased handlers, as required. Typically, a signal handler is bound to
+JavaScript expressions to initiate other events or to simply assign property
+values.
+
+\qml
+import QtQuick 2.0
-\code
Rectangle {
id: button
width: 200; height: 80; color: "lightsteelblue"
@@ -76,9 +163,11 @@ Rectangle {
anchors.fill: parent
onPressed: {
+ // arbitrary JavaScript expression
label.text = "I am Pressed!"
}
onReleased: {
+ // arbitrary JavaScript expression
label.text = "Click Me!"
}
@@ -90,32 +179,36 @@ Rectangle {
text: "Press Me!"
}
}
-\endcode
+\endqml
-During startup, the QML engine will set up and initialize the property
-bindings. The JavaScript conditional operator is a valid property binding.
+Please see the \l{Signal and Handler Event System} documentation for in-depth
+discussion of signals and signal handlers, and see the
+\l{QML Object Attributes} documentation for in-depth discussion of how
+to define the implementation of signal handlers in QML with JavaScript.
-\code
-Rectangle {
- id: colorbutton
- width: 200; height: 80;
- color: mousearea.pressed ? "steelblue" : "lightsteelblue"
- MouseArea {
- id: mousearea
- anchors.fill: parent
- }
-}
-\endcode
+\section2 JavaScript Expressions in Functions
-\section2 Inline JavaScript
+Program logic can also be defined in JavaScript functions. These functions can
+be defined inline in QML documents (as custom methods) or externally in
+imported JavaScript files.
-Small JavaScript functions can be written inline with other QML declarations.
-These inline functions are added as methods to the QML element that contains
-them.
-\code
+
+\section3 Custom Methods
+
+Custom methods can be defined in QML documents and may be called from signal
+handlers, property bindings, or functions in other QML objects. Methods
+defined in this way are often referred to as "inline JavaScript functions" as
+their implementation is included in the QML object type definition
+(QML document), as opposed to an external JavaScript file.
+
+An example of an inline custom method is as follows:
+
+\qml
+import QtQuick 2.0
+
Item {
function factorial(a) {
a = parseInt(a);
@@ -130,72 +223,59 @@ Item {
onClicked: console.log(factorial(10))
}
}
-\endcode
+\endqml
The factorial function will run whenever the MouseArea detects a clicked signal.
-As methods, inline functions on the root element in a QML component can be
-invoked by callers outside the component. If this is not desired, the method
-can be added to a non-root element or, preferably, written in an external
-JavaScript file.
+Importantly, custom methods defined inline in a QML document are exposed to
+other objects, and therefore inline functions on the root object in a QML
+component can be invoked by callers outside the component. If this is not
+desired, the method can be added to a non-root object or, preferably, written
+in an external JavaScript file.
-\section2 JavaScript files
+See the \l{QML Object Attributes} documentation for in-depth discussion of how
+to define custom methods in QML with JavaScript code implementations.
-Large blocks of JavaScript should be written in separate files. These files
-can be imported into QML files using an \c import statement, in the same way
-that \l {QML Modules}{modules} are imported.
-For example, the \c {factorial()} method in the above example for \l {Inline JavaScript}
-could be moved into an external file named \c factorial.js, and accessed like this:
-\code
+\section3 Functions in Imported JavaScript Files
+
+Non-trivial program logic is best separated into external JavaScript files.
+These files can be imported into QML files using an \c import statement, in
+the same way that \l {QML Modules}{modules} are imported.
+
+For example, the \c {factorial()} method in the above example for
+\l{JavaScript Expressions in Custom Methods} could be moved into an external
+file named \c factorial.js, and accessed like this:
+
+\qml
import "factorial.js" as MathFunctions
+
Item {
MouseArea {
anchors.fill: parent
onClicked: console.log(MathFunctions.factorial(10))
}
}
-\endcode
+\endqml
For more information about loading external JavaScript files into QML, read
the section about \l{Importing JavaScript into QML}.
-\section1 JavaScript Expressions
-The \l{JavaScript Runtime}{JavaScript runtime} run regular JavaScript
-expressions as defined by the
-
-\section2 Variables and Properties
-
--variables
--basic data types
--values and assigning
--relate to property binding
-\section2 Conditional Loops
-- for loops et al.
-- conditional operator
-\section2 Data Structures
-- arrays
-- object
-- relate to the content below about valid JS scope, objects, etc.
-- more advanced data types such as accessing QML list
+\section3 Connecting Signals to JavaScript Functions
-\section2 Functions
-- function declaration
-- function assignment (return values)
-- function parameters
-- connecting functions
-- importing libraries, functions
-- difference between JS functions and signals and QML methods
-\section3 Receiving QML Signals in JavaScript
+QML object types which emit signals also provide default signal handlers for
+their signals, as described in a previous section. Sometimes, however, a
+client will want to cause a signal emitted from one object to trigger a
+function defined in another object; and in that case, a signal connection
+is often preferable.
-To receive a QML signal, use the signal's \c connect() method to connect it to a JavaScript
-function.
-
-For example, the following code connects the MouseArea \c clicked signal to the \c jsFunction()
-in \c script.js:
+A signal emitted by a QML object may be connected to a JavaScript function
+by calling the signal's \c connect() method and passing the JavaScript function
+as an argument. For example, the following code connects the MouseArea
+\c clicked signal to the \c jsFunction() in \c script.js:
\table
\row
@@ -203,133 +283,12 @@ in \c script.js:
\li \snippet qml/integrating-javascript/script.js 0
\endtable
-The \c jsFunction() will now be called whenever MouseArea's \c clicked signal is emitted.
+The \c jsFunction() will now be called whenever MouseArea's \c clicked signal
+is emitted.
See \l{QML Signal and Handler Event System#Connecting Signals to Methods and Signals}
{Connecting Signals to Methods and Signals} for more information.
-\section2 Advanced Usage
-- using JS to access QML scene
-- using JS for algorithms
- - sorting, reordering lists
-- how to modify other QML entities with JS
-
-
-
-\section1 Importing JavaScript into QML
-Both relative and absolute JavaScript URLs can be imported. In the case of a
-relative URL, the location is resolved relative to the location of the
-\l {QML Document} that contains the import. If the script file is not accessible,
-an error will occur. If the JavaScript needs to be fetched from a network
-resource, the component's \l {QQmlComponent::status()}{status} is set to
-"Loading" until the script has been downloaded.
-
-Imported JavaScript files are always qualified using the "as" keyword. The
-qualifier for JavaScript files must be unique, so there is always a one-to-one
-mapping between qualifiers and JavaScript files. (This also means qualifiers cannot
-be named the same as built-in JavaScript objects such as \c Date and \c Math).
-
-\section2 Importing One JavaScript File From Another
-
-If a JavaScript file needs to use functions defined inside another JavaScript file,
-the other file can be imported using the \l {QML:Qt::include()}{Qt.include()}
-function. This imports all functions from the other file into the current file's
-namespace.
-
-For example, the QML code below left calls \c showCalculations() in \c script.js,
-which in turn can call \c factorial() in \c factorial.js, as it has included
-\c factorial.js using \l {QML:Qt::include()}{Qt.include()}.
-
-\table
-\row
-\li {1,2} \snippet qml/integrating-javascript/includejs/app.qml 0
-\li \snippet qml/integrating-javascript/includejs/script.js 0
-\row
-\li \snippet qml/integrating-javascript/includejs/factorial.js 0
-\endtable
-
-Notice that calling \l {QML:Qt::include()}{Qt.include()} imports all functions from
-\c factorial.js into the \c MyScript namespace, which means the QML component can also
-access \c factorial() directly as \c MyScript.factorial().
-
-In QtQuick 2.0, support has been added to allow JavaScript files to import other
-JavaScript files and also QML modules using a variation of the standard QML import
-syntax (where all of the previously described rules and qualifications apply).
-
-A JavaScript file may import another in the following fashion:
-\code
-.import "filename.js" as UniqueQualifier
-\endcode
-For example:
-\code
-.import "factorial.js" as MathFunctions
-\endcode
-
-A JavaScript file may import a QML module in the following fashion:
-\code
-.import Module.Name MajorVersion.MinorVersion as UniqueQualifier
-\endcode
-For example:
-\code
-.import Qt.test 1.0 as JsQtTest
-\endcode
-In particular, this may be useful in order to access functionality provided
-via a module API; see qmlRegisterModuleApi() for more information.
-
-Due to the ability of a JavaScript file to import another script or QML module in
-this fashion in QtQuick 2.0, some extra semantics are defined:
-\list
-\li a script with imports will not inherit imports from the QML file which imported it (so accessing Component.error will fail, for example)
-\li a script without imports will inherit imports from the QML file which imported it (so accessing Component.error will succeed, for example)
-\li a shared script (i.e., defined as .pragma library) does not inherit imports from any QML file even if it imports no other scripts
-\endlist
-
-The first semantic is conceptually correct, given that a particular script
-might be imported by any number of QML files. The second semantic is retained
-for the purposes of backwards-compatibility. The third semantic remains
-unchanged from the current semantics for shared scripts, but is clarified here
-in respect to the newly possible case (where the script imports other scripts
-or modules).
-\section2 Code-Behind Implementation Files
-
-Most JavaScript files imported into a QML file are stateful implementations
-for the QML file importing them. In these cases, for QML component instances to
-behave correctly each instance requires a separate copy of the JavaScript objects
-and state.
-
-The default behavior when importing JavaScript files is to provide a unique, isolated
-copy for each QML component instance. The code runs in the same scope as the QML
-component instance and consequently can can access and manipulate the objects and
-properties declared.
-
-\section2 Stateless JavaScript libraries
-
-Some JavaScript files act more like libraries - they provide a set of stateless
-helper functions that take input and compute output, but never manipulate QML
-component instances directly.
-
-As it would be wasteful for each QML component instance to have a unique copy of
-these libraries, the JavaScript programmer can indicate a particular file is a
-stateless library through the use of a pragma, as shown in the following example.
-
-\code
-// factorial.js
-.pragma library
-
-function factorial(a) {
- a = parseInt(a);
- if (a <= 0)
- return 1;
- else
- return a * factorial(a - 1);
-}
-\endcode
-
-The pragma declaration must appear before any JavaScript code excluding comments.
-
-As they are shared, stateless library files cannot access QML component instance
-objects or properties directly, although QML values can be passed as function
-parameters.
@@ -338,16 +297,22 @@ parameters.
It is occasionally necessary to run some imperative code at application (or
component instance) startup. While it is tempting to just include the startup
-script as \e {global code} in an external script file, this can have severe limitations
-as the QML environment may not have been fully established. For example, some objects
-might not have been created or some \l {Property Binding}s may not have been run.
-\l {QML JavaScript Restrictions} covers the exact limitations of global script code.
+script as \e {global code} in an external script file, this can have severe
+limitations as the QML environment may not have been fully established. For
+example, some objects might not have been created or some
+\l {Property Binding}s may not have been run. \l {QML JavaScript Restrictions}
+covers the exact limitations of global script code.
+
+Every QML object has an \e attached \l Component property that references the
+component within which the object was instantiated. Every \l Component
+will emit a \c completed signal, and thus every object can define an
+implementation for the \c onCompleted() handler which can be used to trigger the
+execution of script code at startup after the QML environment has been
+completely established. For example:
-The QML \l Component element provides an \e attached \c onCompleted property that
-can be used to trigger the execution of script code at startup after the
-QML environment has been completely established. For example:
+\qml
+import QtQuick 2.0
-\code
Rectangle {
function startupFunction() {
// ... startup code
@@ -355,41 +320,37 @@ Rectangle {
Component.onCompleted: startupFunction();
}
-\endcode
+\endqml
-Any element in a QML file - including nested elements and nested QML component
-instances - can use this attached property. If there is more than one \c onCompleted()
-handler to execute at startup, they are run sequentially in an undefined order.
+Any object in a QML file - including nested objects and nested QML component
+instances - can use this attached property. If there is more than one
+\c onCompleted() handler to execute at startup, they are run sequentially in
+an undefined order.
-Likewise, the \l {Component::onDestruction} attached property is triggered on
-component destruction.
+Likewise, the \l {Component::onDestruction} handler definitions are triggered
+on component destruction.
-\section1 JavaScript and Property Binding
-Property bindings can be created in JavaScript by assigning the property the value returned
-by calling Qt.binding() where the parameter to Qt.binding() is a \c function
-that returns the required value.
-See \l {qml-javascript-assignment}{Property Assignment versus Property Binding} for details.
-\section1 QML JavaScript Restrictions
+\section1 JavaScript Expression Restrictions in QML
QML executes standard JavaScript code, with the following restrictions:
\list
\li JavaScript code cannot modify the global object.
-In QML, the global object is constant - existing properties cannot be modified or
-deleted, and no new properties may be created.
+In QML, the global object is constant - existing properties cannot be modified
+or deleted, and no new properties may be created.
-Most JavaScript programs do not intentionally modify the global object. However,
-JavaScript's automatic creation of undeclared variables is an implicit modification
-of the global object, and is prohibited in QML.
+Most JavaScript programs do not intentionally modify the global object.
+However, JavaScript's automatic creation of undeclared variables is an implicit
+modification of the global object, and is prohibited in QML.
-Assuming that the \c a variable does not exist in the scope chain, the following code
-is illegal in QML.
+Assuming that the \c a variable does not exist in the scope chain, the
+following code is illegal in QML:
\code
// Illegal modification of undeclared variable
@@ -559,5 +520,3 @@ the references will be affected.
\snippet qml/integrating-javascript/scarceresources/avatarExample.cpp 5
*/
-
-*/
diff --git a/src/qml/doc/src/javascript/hostenvironment.qdoc b/src/qml/doc/src/javascript/hostenvironment.qdoc
index 01c55a00ef..ad2b905e22 100644
--- a/src/qml/doc/src/javascript/hostenvironment.qdoc
+++ b/src/qml/doc/src/javascript/hostenvironment.qdoc
@@ -77,7 +77,7 @@ QML implements the following restrictions for JavaScript code:
\li The value of \c this is undefined in QML in the majority of contexts.
\endlist
-See \l {QML JavaScript Restrictions} for more details on these restrictions.
+See \l {JavaScript Expression Restrictions in QML} for more details on these restrictions.
*/
diff --git a/src/qml/doc/src/javascript/imports.qdoc b/src/qml/doc/src/javascript/imports.qdoc
index 138120345c..9e71368f81 100644
--- a/src/qml/doc/src/javascript/imports.qdoc
+++ b/src/qml/doc/src/javascript/imports.qdoc
@@ -28,4 +28,159 @@
\page qtqml-javascript-imports.html
\title Importing JavaScript Files In QML Documents
\brief Description of how to import and use JavaScript files in QML documents
+
+Both relative and absolute JavaScript URLs can be imported in QML documents.
+In the case of a relative URL, the location is resolved relative to the
+location of the \l {QML Document} that contains the import. If the script
+file is not accessible, an error will occur. If the JavaScript needs to be
+fetched from a network resource, the component's
+\l {QQmlComponent::status()}{status} is set to "Loading" until the script has
+been downloaded.
+
+Imported JavaScript files are always qualified using the "as" keyword. The
+qualifier for JavaScript files must be unique, so there is always a one-to-one
+mapping between qualifiers and JavaScript files. (This also means qualifiers
+cannot be named the same as built-in JavaScript objects such as \c Date and
+\c Math).
+
+The functions defined in an imported JavaScript file are available to objects
+defined in the importing QML document, via the \c{"Qualifier.functionName()"}
+syntax.
+
+\section1 Importing One JavaScript File From Another
+
+In QtQuick 2.0, support has been added to allow JavaScript files to import
+other JavaScript files and also QML type namespaces using a variation of the
+standard QML import syntax (where all of the previously described rules and
+qualifications apply).
+
+A JavaScript file may import another in the following fashion:
+\code
+.import "filename.js" as Qualifier
+\endcode
+For example:
+\code
+.import "factorial.js" as MathFunctions
+\endcode
+
+A JavaScript file may import a QML type namespace in the following fashion:
+\code
+.import TypeNamespace MajorVersion.MinorVersion as Qualifier
+\endcode
+
+For example:
+\code
+.import Qt.test 1.0 as JsQtTest
+\endcode
+
+In particular, this may be useful in order to access functionality provided
+via a module API; see qmlRegisterModuleApi() for more information.
+
+Due to the ability of a JavaScript file to import another script or QML module
+in this fashion in QtQuick 2.0, some extra semantics are defined:
+\list
+\li a script with imports will not inherit imports from the QML file which imported it (so accessing Component.error will fail, for example)
+\li a script without imports will inherit imports from the QML file which imported it (so accessing Component.error will succeed, for example)
+\li a shared script (i.e., defined as .pragma library) does not inherit imports from any QML file even if it imports no other scripts
+\endlist
+
+The first semantic is conceptually correct, given that a particular script
+might be imported by any number of QML files. The second semantic is retained
+for the purposes of backwards-compatibility. The third semantic remains
+unchanged from the current semantics for shared scripts, but is clarified here
+in respect to the newly possible case (where the script imports other scripts
+or modules).
+
+
+\section2 Code-Behind Implementation Files
+
+Most JavaScript files imported into a QML file are stateful implementations
+for the QML file importing them. In these cases, for QML component instances
+to behave correctly each instance requires a separate copy of the JavaScript
+objects and state.
+
+The default behavior when importing JavaScript files is to provide a unique,
+isolated copy for each QML component instance. If that JavaScript file does
+not import any other JavaScript files or QML type namespaces, its code will run
+in the same scope as the QML component instance and consequently can can access
+and manipulate the objects and properties declared in that QML component.
+Otherwise, it will have its own unique scope, and objects and properties of the
+QML component should be passed to the functions of the JavaScript file as
+parameters if they are required.
+
+\section2 Shared JavaScript Files (Libraries)
+
+Some JavaScript files act more like libraries - they provide a set of helper
+functions that take input and compute output, but never manipulate QML
+component instances directly.
+
+As it would be wasteful for each QML component instance to have a unique copy of
+these libraries, the JavaScript programmer can indicate a particular file is a
+shared library through the use of a pragma, as shown in the following example.
+
+\code
+// factorial.js
+.pragma library
+
+var factorialCount = 0;
+
+function factorial(a) {
+ a = parseInt(a);
+
+ // factorial recursion
+ if (a > 0)
+ return a * factorial(a - 1);
+
+ // shared state
+ factorialCount += 1;
+
+ // recursion base-case.
+ return 1;
+}
+
+function factorialCallCount() {
+ return factorialCount;
+}
+\endcode
+
+The pragma declaration must appear before any JavaScript code excluding comments.
+
+Note that multiple QML documents can import \c{"factorial.js"} and call the
+factorial and factorialCallCount functions that it provides. The state of the
+JavaScript import is shared across the QML documents which import it, and thus
+the return value of the factorialCallCount function may be non-zero when called
+within a QML document which never calls the factorial function.
+
+As they are shared, .pragma library files cannot access QML component instance
+objects or properties directly, although QML values can be passed as function
+parameters.
+
+\section1 Including One JavaScript File From Another
+
+When a JavaScript file is imported, it must be imported with a qualifier. The
+functions in that file are then accessible from the importing script via the
+qualifier (that is, as \tt{Qualifier.functionName(params)}). Sometimes it is
+desirable to have the functions made available in the importing context without
+needing to qualify them, and in this circumstance the \l{QML:Qt::include()}
+{Qt.include()} function may be used to include one JavaScript file from another.
+This copies all functions from the other file into the current file's
+namespace, but ignores all pragmas and imports defined in that file.
+
+For example, the QML code below left calls \c showCalculations() in \c script.js,
+which in turn can call \c factorial() in \c factorial.js, as it has included
+\c factorial.js using \l {QML:Qt::include()}{Qt.include()}.
+
+\table
+\row
+\li {1,2} \snippet qml/integrating-javascript/includejs/app.qml 0
+\li \snippet qml/integrating-javascript/includejs/script.js 0
+\row
+\li \snippet qml/integrating-javascript/includejs/factorial.js 0
+\endtable
+
+Notice that calling \l {QML:Qt::include()}{Qt.include()} copies all functions
+from \c factorial.js into the \c MyScript namespace, which means the QML
+component can also access \c factorial() directly as \c MyScript.factorial().
+
+
*/