summaryrefslogtreecommitdiffstats
path: root/doc/src
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src')
-rw-r--r--doc/src/declarative/focus.qdoc88
-rw-r--r--doc/src/declarative/modules.qdoc1
-rw-r--r--doc/src/declarative/pics/qml-scope.pngbin34888 -> 47564 bytes
-rw-r--r--doc/src/declarative/qtbinding.qdoc79
-rw-r--r--doc/src/declarative/qtdeclarative.qdoc10
-rw-r--r--doc/src/declarative/scope.qdoc314
6 files changed, 448 insertions, 44 deletions
diff --git a/doc/src/declarative/focus.qdoc b/doc/src/declarative/focus.qdoc
index 8733b2d..ec6a02f 100644
--- a/doc/src/declarative/focus.qdoc
+++ b/doc/src/declarative/focus.qdoc
@@ -58,12 +58,14 @@ When the user presses or releases a key, the following occurs:
\o The key event is delivered by the scene to the QML \l Item with \e {active focus}. If no \l Item has \e {active focus}, the key event is \l {QEvent::ignore()}{ignored} and regular Qt key handling continues.
\o If the QML \l Item with \e {active focus} accepts the key event, propagation stops. Otherwise the event is "bubbled up", by recursively passing it to each \l Item's parent until either the event is accepted, or the root \l Item is reached.
-If the \c {Rectangle} element in the following example has active focus and the \e A key is pressed, it will bubble up to the \c {KeyActions}. However, pressing the \e B key will bubble up to the root item and thus subsequently be \l {QEvent::ignore()}{ignored}.
+If the \c {Rectangle} element in the following example has active focus and the \e A key is pressed,
+it will bubble up to its parent. However, pressing the \e B key will bubble up to the root
+item and thus subsequently be \l {QEvent::ignore()}{ignored}.
\code
Item {
- KeyActions {
- keyA: "print('Key A was pressed')"
+ Item {
+ Keys.onPressed: if (event.key == Qt.Key_A) { print('Key A was pressed'); event.accepted = true }
Rectangle {}
}
}
@@ -91,8 +93,8 @@ An \l Item requests focus by setting the \c {Item::focus} property to true.
For very simple cases simply setting the \c {Item::focus} property is sometimes
sufficient. If we run the following example in the \c qmlviewer, we see that
-the \c {KeyActions} element has \e {active focus} and pressing the
-\e A, \e B, or \e C keys modifies the text appropriately.
+the \c {keyHandler} element has \e {active focus} and pressing the 'A', 'B'
+or 'C' keys modifies the text appropriately.
\table
\row
@@ -100,11 +102,17 @@ the \c {KeyActions} element has \e {active focus} and pressing the
Rectangle {
color: "lightsteelblue"; width: 240; height: 25
Text { id: myText }
- KeyActions {
+ Item {
+ id: keyHandler
focus: true
- keyA: "myText.text = 'Key A was pressed'"
- keyB: "myText.text = 'Key B was pressed'"
- keyC: "myText.text = 'Key C was pressed'"
+ Keys.onPressed: {
+ if (event.key == Qt.Key_A)
+ myText.text = 'Key A was pressed'
+ else if (event.key == Qt.Key_B)
+ myText.text = 'Key B was pressed'
+ else if (event.key == Qt.Key_C)
+ myText.text = 'Key C was pressed'
+ }
}
}
\endcode
@@ -134,22 +142,34 @@ Rectangle {
Rectangle {
color: "lightsteelblue"; width: 240; height: 25
Text { id: myText }
- KeyActions {
+ Item {
+ id: keyHandler
focus: true
- keyA: "myText.text = 'Key A was pressed'"
- keyB: "myText.text = 'Key B was pressed'"
- keyC: "myText.text = 'Key C was pressed'"
+ Keys.onPressed: {
+ if (event.key == Qt.Key_A)
+ myText.text = 'Key A was pressed'
+ else if (event.key == Qt.Key_B)
+ myText.text = 'Key B was pressed'
+ else if (event.key == Qt.Key_C)
+ myText.text = 'Key C was pressed'
+ }
}
}
Rectangle {
y: 30; focus: true
color: "lightsteelblue"; width: 240; height: 25
Text { id: myText }
- KeyActions {
+ Item {
+ id: keyHandler
focus: true
- keyA: "myText.text = 'Key A was pressed'"
- keyB: "myText.text = 'Key B was pressed'"
- keyC: "myText.text = 'Key C was pressed'"
+ Keys.onPressed: {
+ if (event.key == Qt.Key_A)
+ myText.text = 'Key A was pressed'
+ else if (event.key == Qt.Key_B)
+ myText.text = 'Key B was pressed'
+ else if (event.key == Qt.Key_C)
+ myText.text = 'Key C was pressed'
+ }
}
}
}
@@ -166,9 +186,9 @@ of \c {Item::focus} in the other two instances is reverted back to false. This
is exactly the opposite of what was wanted!
This problem is fundamentally one of visibility. The \c {MyWidget}
-components each set their \c {KeyActions} as focused as that is all they can
+components each set their \c {keyHandler} Items as focused as that is all they can
do - they don't know how they are going to be used, but they do know that when
-they're in use their \c {KeyActions} element is what needs focus. Likewise
+they're in use their \c {keyHandler} element is what needs focus. Likewise
the code that uses the \c {MyWidget}'s sets the second \c {MyWidget} as
focused because, while it doesn't know exactly how the \c {MyWidget} is
implemented, it knows that it wants the second one to be focused. No one piece
@@ -191,11 +211,17 @@ FocusScope {
Rectangle {
color: "lightsteelblue"; width: 240; height: 25
Text { id: myText }
- KeyActions {
+ Item {
+ id: keyHandler
focus: true
- keyA: "myText.text = 'Key A was pressed'"
- keyB: "myText.text = 'Key B was pressed'"
- keyC: "myText.text = 'Key C was pressed'"
+ Keys.onPressed: {
+ if (event.key == Qt.Key_A)
+ myText.text = 'Key A was pressed'
+ else if (event.key == Qt.Key_B)
+ myText.text = 'Key B was pressed'
+ else if (event.key == Qt.Key_C)
+ myText.text = 'Key C was pressed'
+ }
}
}
}
@@ -205,8 +231,11 @@ FocusScope {
Conceptually \e {focus scopes} are quite simple.
\list
-\o Within each \e {focus scope} one element may have \c {Item::focus} set to true. If more than one \l Item has the \c {Item::focus} property set, the first is selected and the others are unset, just like when there are no \e {focus scopes}.
-\o When a \e {focus scope} receives \e {active focus}, the contained element with \c {Item::focus} set (if any) also gets \e {active focus}. If this element is
+\o Within each \e {focus scope} one element may have \c {Item::focus} set to true.
+If more than one \l Item has the \c {Item::focus} property set, the first is selected
+and the others are unset, just like when there are no \e {focus scopes}.
+\o When a \e {focus scope} receives \e {active focus}, the contained element with
+\c {Item::focus} set (if any) also gets \e {active focus}. If this element is
also a \l FocusScope, the proxying behaviour continues. Both the
\e {focus scope} and the sub-focused item will have \c {Item::focus} set.
\endlist
@@ -270,8 +299,11 @@ Rectangle {
}
delegate: FocusScope {
width: contents.width; height: contents.height
- Text { text: name }
- KeyActions { return: "print(name)"; focus: true }
+ Text {
+ focus: true
+ text: name
+ Keys.onReturnPressed: print(name)
+ }
}
}
}
@@ -285,7 +317,7 @@ property. As the \l ListView is a \e {focus scope}, this doesn't effect the
rest of the application. However, if the \l ListView itself has
\e {active focus} this causes the delegate itself to receive \e {active focus}.
In this example, the root element of the delegate is also a \e {focus scope},
-which in turn gives \e {active focus} to the \c {KeyActions} element that
+which in turn gives \e {active focus} to the \c {Text} element that
actually performs the work of handling the \e {Return} key.
All of the QML view classes, such as \l PathView and \l GridView, behave
diff --git a/doc/src/declarative/modules.qdoc b/doc/src/declarative/modules.qdoc
index 3a6495d..2f7cb57 100644
--- a/doc/src/declarative/modules.qdoc
+++ b/doc/src/declarative/modules.qdoc
@@ -40,7 +40,6 @@
****************************************************************************/
/*!
-\target qmlmodules
\page qmlmodules.html
\title Modules
diff --git a/doc/src/declarative/pics/qml-scope.png b/doc/src/declarative/pics/qml-scope.png
index 05403db..be025c8 100644
--- a/doc/src/declarative/pics/qml-scope.png
+++ b/doc/src/declarative/pics/qml-scope.png
Binary files differ
diff --git a/doc/src/declarative/qtbinding.qdoc b/doc/src/declarative/qtbinding.qdoc
index f6fe069..1831cf8 100644
--- a/doc/src/declarative/qtbinding.qdoc
+++ b/doc/src/declarative/qtbinding.qdoc
@@ -44,15 +44,93 @@
\target qtbinding
\title Using QML in C++ Applications
+The QML API is split into three main classes - QmlEngine, QmlComponent and QmlContext.
+QmlEngine provides the environment in which QML is run, QmlComponent encapsulates
+\l {QML Documents}, and QmlContext allows applications to expose data to QML component instances.
+
+\section1 Basic Usage
+
+Every application requires at least one QmlEngine. A QmlEngine allows the configuration of
+global settings that apply to all the QML component instances - such as the QNetworkAccessManager
+that is used for network communications, and the path used for persistent storage.
+Multiple QmlEngine's are only needed if the application requires these settings to differ
+between QML component instances.
+
+\l {QML Documents} are loaded using the QmlComponent class. Each QmlComponent instance
+represents a single QML document. A QmlComponent can be passed a document URL, or raw text
+representing the content of the document. The document URL can be a local filesystem URL, or
+any network URL supported by QNetworkAccessManager.
+
+QML component instances can then be created by calling the QmlComponent::create() method. Here's
+an example of loading a QML document, and creating an object from it.
+
+\code
+QmlEngine *engine = new QmlEngine(parent);
+QmlComponent component(engine, QUrl("main.qml"));
+QObject *myObject = component.create();
+\endcode
+
+\section1 Exposing Data
+
+QML components are instantiated in a QmlContext. A context allows the application to expose data
+to the QML component instance. A single QmlContext can be used to instantiate all the objects
+used by an application, or several QmlContext can be created for more fine grained control over
+the data exposed to each instance. If a context is not passed to the QmlComponent::create()
+method, the QmlEngine's \l {QmlEngine::rootContext()}{root context} is used.
+
+To expose data to a QML component instance, applications set \l {QmlContext::setContextProperty()}{context properties} which are then accessible by name from QML \l {Property Binding}s and
+\l {ECMAScript Blocks}.
+
+\section1 Network Components
+
+If the URL passed to QmlComponent is a network resource, or if the QML document references a
+network resource, the QmlComponent has to fetch the network data before it is able to create
+objects. In this case, the QmlComponent will have a \l {QmlComponent::Loading}{Loading}
+\l {QmlComponent::status()}{status}. An application will have to wait until the component
+is \l {QmlComponent::Ready}{Ready} before calling \l {QmlComponent::create()}.
+
+The following example shows how to load a QML file from a network resource. After creating
+the QmlComponent, it tests whether the component is loading. If it is, it connects to the
+QmlComponent::statusChanged() signal and otherwise calls the \c {continueLoading()} method
+directly. This test is necessary, even for URLs that are known to be remote, just in case
+the component has been cached and is ready immediately.
+
+\code
+MyApplication::MyApplication()
+{
+ // ...
+ component = new QmlComponent(engine, QUrl("http://www.example.com/main.qml"));
+ if (component->isLoading())
+ QObject::connect(component, SIGNAL(statusChanged(QmlComponent::Status)),
+ this, SLOT(continueLoading()));
+ else
+ continueLoading();
+}
+
+void MyApplication::continueLoading()
+{
+ if (component->isError()) {
+ qWarning() << component->errors();
+ } else {
+ QObject *myObject = component->create();
+ }
+}
+\endcode
+
\section1 TODO
\list
\o QmlEngine and QmlComponent
\o QmlContext and data
\o QBindableMap
\o QAbstractItemModel Data models
+\o QmlView
\endlist
+*/
+
+/*
\section1 Overview
+
The QML mechanisms of data binding can also be used to bind Qt C++ objects.
The data binding framework is based on Qt's property system (see the Qt documentation for more details on this system). If a binding is meant to be dynamic (where changes in one object are reflected in another object), \c NOTIFY must be specified for the property being tracked. If \c NOTIFY is not specified, any binding to that property will be an 'intialization' binding (the tracking object will be updated only once with the initial value of the tracked object).
@@ -60,7 +138,6 @@ The data binding framework is based on Qt's property system (see the Qt document
Relevant items can also be bound to the contents of a Qt model.
For example, ListView can make use of data from a QAbstractItemModel-derived model.
-
\section1 Passing Data Between C++ and QML
Data binding provides one method of data transfer between C++ and QML.
diff --git a/doc/src/declarative/qtdeclarative.qdoc b/doc/src/declarative/qtdeclarative.qdoc
index 45f9347..ebf7880 100644
--- a/doc/src/declarative/qtdeclarative.qdoc
+++ b/doc/src/declarative/qtdeclarative.qdoc
@@ -74,8 +74,7 @@ completely new applications. QML is fully \l {Extending QML}{extensible from C+
\list
\o \l {Introduction to the QML language}
\o \l {Tutorial}{Tutorial: 'Hello World'}
-\o \l {tutorials-declarative-contacts.html}{Tutorial: 'Introduction to QML'}
-\o \l {advtutorial.html}{Advanced Tutorial: 'Same Game'}
+\o \l {advtutorial.html}{Tutorial: 'Same Game'}
\o \l {QML Examples and Walkthroughs}
\o \l {Using QML in C++ Applications}
\endlist
@@ -89,7 +88,7 @@ completely new applications. QML is fully \l {Extending QML}{extensible from C+
\o \l {qmlmodels}{Data Models}
\o \l {anchor-layout}{Anchor-based Layout}
\o \l {qmlanimation}{Animation}
-\o \l {qmlmodules}{Modules}
+\o \l {qmlmodules.html}{Modules}
\o \l {qmlfocus}{Keyboard Focus}
\o \l {Extending types from QML}
\endlist
@@ -105,4 +104,9 @@ completely new applications. QML is fully \l {Extending QML}{extensible from C+
\o \l {Extending QML}
\o \l {qtbinding}{QML/C++ Data Binding}
\endlist
+
+\section1 Deprecated
+
+\o \l {tutorials-declarative-contacts.html}{Tutorial: 'Introduction to QML'}
+
*/
diff --git a/doc/src/declarative/scope.qdoc b/doc/src/declarative/scope.qdoc
index 4c613df..14efa59 100644
--- a/doc/src/declarative/scope.qdoc
+++ b/doc/src/declarative/scope.qdoc
@@ -46,41 +46,333 @@
\l {Property Binding}s and \l {ECMAScript Blocks} are executed in a scope chain automatically
established by QML when constructing a component instance. QML is a \e {dynamically scoped}
language. Different object instances instantiated from the same component can exist in
-dramatically different scope chains.
+different scope chains.
\image qml-scope.png
-\section1 Variable object
+\section1 ECMAScript Variable object
-Where local variables are stored. Not really applicable to bindings.
+Each binding and script block has its own distinct ECMAScript variable object where local
+variables are stored. That is, local variables from different bindings and script blocks never
+conflict.
-\section1 QML Scope object
+\section1 Element Type Names
-Principally for the \c parent property.
+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.
+
+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
+
+Text {
+ id: root
+ scale: root.PathView.scale
+ horizontalAlignment: Text.AlignLeft
+}
+\endcode
+\o
+\code
+import Qt 4.6 as MyQt
+
+Text {
+ id: root
+ scale: root.MyQt.PathView.scale
+ horizontalAlignment: MyQt.Text.AlignLeft
+}
+\endcode
+\endtable
+
+\section1 QML Local Scope
+
+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 declarated. The following example shows
+three different bindings, and the component that dictates their local scope.
+
+\table
+\row
+\o
+\code
+// main.qml
+import Qt 4.6
+
+Rectangle { // Local scope component for binding 1
+ id: root
+ property string text
+
+ Button {
+ text: root.text // binding 1
+ }
+
+ 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
+
+ Text {
+ text: root.text // binding 3
+ }
+}
+\endcode
+\endtable
+
+Inside the local scope, four "sub-scopes" exist. Each "sub-scope" is searched in order when
+resolving a name - names in a higher "sub-scopes" shadow those in lower sub-scopes.
+
+\section2 IDs
+
+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.
+
+This is an example of using IDs within bindings.
\code
Item {
- anchors.fill: parent
+ 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}.
+
+\code
+Item {
+ Script {
+ function getValue() { return 10; } // Method 1
+ }
+
+ Rectangle {
+ Script {
+ function getValue() { return 11; } // Method 2
+ function getValue2() { return getValue(); } // Method 3
+ }
+
+ 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}.
+
+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.
+
+\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
+ }
}
\endcode
-vs
+One notable characteristic of the scope object is its interaction with \l {Attached Properties}.
+As attached properties exist on all object, 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}.
+
+\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
+ }
+ }
+}
+\endcode
+
+\e TODO
+
+\list
+\o scope object for PropertyChanges
+\endlist
+
+\section2 Root Object
+
+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.
\code
Item {
- anchors.fill: this.parent
+ property string description
+ property int fontSize
+
+ Text {
+ text: description
+ font.pixelSize: fontSize
+ }
}
\endcode
\section1 QML Component chain
-Principally for propogating properties around the component.
+When a QML component is instantiated it is given a parent component instance. The parent
+component instance is immutable - it is not effected, 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.
+
+For each component instance in the chain, the following are examined:
+
+\list 1
+\o IDs
+\o Script Methods
+\o Root Object
+\endlist
+
+This list is a sub-set of that in the \l {QML Local Scope}.
+
+Sub-components used within a component have their parent component instance set to the component
+instance that created them. 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");
+ }
+
+ 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
+ }
+ MouseRegion {
+ anchors.fill: parent
+ onClicked: buttonClicked(text)
+ }
+}
+\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.
+
+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.
+
+\code
+Item {
+ property color delegateColor: "red"
+
+ ListView {
+ delegate: Component {
+ Rectangle {
+ color: delegateColor
+ }
+ }
+ }
+}
+\endcode
\section1 QmlContext chain
-App provided data.
+The \l QmlContext chain allows C++ applications to pass data into QML applications.
+\l QmlComponent object instances created from C++ are passed a \l QmlContext in which they
+are created. Variables defined in this context appear in the scope chain. Each QmlContext
+also defines a parent context. Variables in child QmlContext's shadow those in its parent.
+
+Consider the following QmlContext tree.
+
+\image qml-context-tree.png
+
+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}.
+
+\code
+import Qt 4.6
+
+Rectangle {
+ id: myRect
+ width: 100; height: 100
+ color: background
+}
+\endcode
\section1 QML Global Object
-Contains all the properties ECMAScript defines, plus some QML ones. Documented \l {QML Global Object}.
+The \l {QML Global Object} contains all the properties of the ECMAScript global object, plus some
+QML specific extensions.
*/