aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/doc
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 /src/qml/doc
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>
Diffstat (limited to 'src/qml/doc')
-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().
+
+
*/