diff options
Diffstat (limited to 'doc')
149 files changed, 6291 insertions, 2 deletions
diff --git a/doc/doc.pri b/doc/doc.pri index 66953e6..b62c0fc 100644 --- a/doc/doc.pri +++ b/doc/doc.pri @@ -25,13 +25,14 @@ macx { ADP_DOCS_QDOCCONF_FILE = qt-build-docs.qdocconf } QT_DOCUMENTATION = ($$QDOC qt-api-only.qdocconf assistant.qdocconf designer.qdocconf \ - linguist.qdocconf qmake.qdocconf) && \ + linguist.qdocconf qmake.qdocconf qml.qdocconf) && \ (cd $$QT_BUILD_TREE && \ $$GENERATOR doc-build/html-qt/qt.qhp -o doc/qch/qt.qch && \ $$GENERATOR doc-build/html-assistant/assistant.qhp -o doc/qch/assistant.qch && \ $$GENERATOR doc-build/html-designer/designer.qhp -o doc/qch/designer.qch && \ $$GENERATOR doc-build/html-linguist/linguist.qhp -o doc/qch/linguist.qch && \ - $$GENERATOR doc-build/html-qmake/qmake.qhp -o doc/qch/qmake.qch \ + $$GENERATOR doc-build/html-qmake/qmake.qhp -o doc/qch/qmake.qch && \ + $$GENERATOR doc-build/html-qml/qml.qhp -o doc/qch/qml.qch \ ) win32-g++:isEmpty(QMAKE_SH) { diff --git a/doc/src/declarative/anchor-layout.qdoc b/doc/src/declarative/anchor-layout.qdoc new file mode 100644 index 0000000..f3c0f4a --- /dev/null +++ b/doc/src/declarative/anchor-layout.qdoc @@ -0,0 +1,70 @@ +/*! +\page anchor-layout.html +\target anchor-layout +\title Anchor-based Layout in QML + +In addition to the more traditional \l Grid, \l Row, and \l Column, QML also provides a way to layout items using the concept of anchors. Each item can be thought of as having a set of 6 invisible "anchor lines": \e left, \e horizontalCenter, \e right, \e top, \e verticalCenter, and \e bottom. + +\image edges_qml.png + +The QML anchoring system allows you to define relationships between the anchor lines of different items. For example, you can write: + +\code +Rectangle { id: Rect1; ... } +Rectangle { id: Rect2; anchors.left: Rect1.right; ... } +\endcode + +In this case, the left edge of \e Rect2 is bound to the right edge of Rect1, producing the following: + +\image edge1.png + +The anchoring system also allows you to specify margins and offsets. Margins specify the amount of empty space to leave to the outside of an item, while offsets allow you to manipulate positioning using the center anchor lines. Note that margins specified using the anchor layout system only have meaning for anchors; they won't have any effect when using other layouts or absolute positioning. + +\image margins_qml.png + +The following example specifies a left margin: + +\code +Rectangle { id: Rect1; ... } +Rectangle { id: Rect2; anchors.left: Rect1.right; anchors.leftMargin: 5; ... } +\endcode + +In this case, a margin of 5 pixels is reserved to the left of \e Rect2, producing the following: + +\image edge2.png + +You can specify multiple anchors. For example: + +\code +Rectangle { id: Rect1; ... } +Rectangle { id: Rect2; anchors.left: Rect1.right; anchors.top: Rect1.bottom; ... } +\endcode + +\image edge3.png + +By specifying multiple horizontal or vertical anchors you can control the size of an item. For example: + +\code +Rectangle { id: Rect1; x: 0; ... } +Rectangle { id: Rect2; anchors.left: Rect1.right; anchors.right: Rect3.left; ... } +Rectangle { id: Rect3; x: 150; ... } +\endcode + +\image edge4.png + +\section1 Limitations + +For performance reasons, you can only anchor an item to its siblings and direct parent. For example, the following anchor would be considered invalid and would produce a warning: + +\badcode +Item { + id: Group1 + Rectangle { id: Rect1; ... } +} +Item { + id: Group2 + Rectangle { id: Rect2; anchors.left: Rect1.right; ... } // invalid anchor! +} +\endcode + +*/ diff --git a/doc/src/declarative/animation.qdoc b/doc/src/declarative/animation.qdoc new file mode 100644 index 0000000..9554ad5 --- /dev/null +++ b/doc/src/declarative/animation.qdoc @@ -0,0 +1,165 @@ +/*! +\page qmlanimation.html +\target qmlanimation +\title QML Animation + +QML supports three different forms of animation - basic property animation, +states and transitions and property behaviors. + +\section1 Property Animation + +Animation in QML is done by animating properties of objects. + +Any property of a recognizable type can be animated. Currently those types include: +\list +\o qreal +\o int +\o Most of QVariant's built-in types +\endlist + +Animations can also involve numerous properties on numerous objects. + +Other Features: +\list +\o Support for a large set of parameterized easing curves. (based on the Penner easing equations) +\o Animation synchronization +\endlist + +The simplest form of animation is using \l NumberAnimation + +The following example creates a bouncing effect: +\code +Rectangle { + id: rect + width: 120; height: 200; color: "white" + Image { + id: img + source: "qt-logo.png" + x: 60-img.width/2 + y: 0 + y: SequentialAnimation { + running: true + repeat: true + NumberAnimation { to: 200-img.height; easing: "easeOutBounce"; duration: 2000 } + PauseAnimation { duration: 1000 } + NumberAnimation { to: 0; easing: "easeOutQuad"; duration: 1000 } + } + } +} +\endcode + +\image propanim.gif + +\target states-transitions +\section1 States and Transitions + +\section2 States + +QML states describe user interface configurations, including: +\list +\o What UI elements are present +\o The properties of those elements (including how they behave) +\o What actions are available +\endlist + +A state can also be thought of as a set of batched changes from a default configuration. + +Examples of states in modern UI: +\list +\o A Contacts application has a 'View Contact' state and an 'Edit Contact' State. In the first state the information presented is static (using labels), and in the second it is editable (using editors). +\o A button has a pressed and unpressed state. When pressed the text moves down and to the right, and the button has a slightly darker appearance. +\endlist + +In QML: +\list +\o Any object can use states. +\o There is a default state. The default state can be explicitly set. +\o A state can affect other the properties of other objects, not just the object owning the state (and not just that object's children). +\endlist + +The following example shows a simple use of states. In the default state \c myrect is positioned at 0,0. In the 'moved' state it is positioned at 50,50. + +\code +Item { + Rectangle { + id: myrect + width: 100 + height: 100 + } + states: [ + State { + name: "moved" + PropertyChanges { + target: myrect + x: 50 + y: 50 + } + } + ] +} +\endcode + +\section2 Transitions + +QML transitions describe animations to perform when state changes occur. + +For the previous example, a transition could describe how \c myrect moved from its initial position to its new position: + +\code +transitions: [ + Transition { + NumberAnimation { + properties: "x,y" + easing: "easeOutBounce" + duration: 200 + } + } +] +\endcode + +QML transitions can use selectors to determine which state changes a transition should apply to: + +\code +Transition { + from: "*" + to: "Details" + ... +} +\endcode + +Transitions can happen in parallel, in sequence, or in any combination of the two: + +\code +Transition { + from: "*" + to: "MyState" + reversible: true + SequentialAnimation { + ColorAnimation { + property: "color" + duration: 1000 + } + PauseAnimation { + duration: 1000 + } + ParallelAnimation { + NumberAnimation { + duration: 1000 + easing: "easeOutBounce" + target: box1 + properties: "x,y" + } + NumberAnimation { + duration: 1000 + target: box2 + properties: "x,y" + } + } + } +} +\endcode + +\section1 Property Behaviors + +\note Property behaviors are currently experimental. +*/ diff --git a/doc/src/declarative/basictypes.qdoc b/doc/src/declarative/basictypes.qdoc new file mode 100644 index 0000000..ae942fc --- /dev/null +++ b/doc/src/declarative/basictypes.qdoc @@ -0,0 +1,195 @@ +/*! + \page basicqmltypes.html + \title Common QML Types + + QML uses a range of property types, which you will see + referenced throughout the element documentation. Almost all of them are + exactly what you would expect. + + \target basicqmlint + \section1 int + + An integer or \c int is a whole numbers like 0, 10 or -20. The possible \c int + values range from around -2000000000 to around 2000000000, although most + elements will only accept a reduced range (which they mention in their + documentation). + + Example: + \qml + Item { width: 100; height: 200 } + \endqml + + \target basicqmlbool + \section1 bool + + A boolean or \c bool is a binary true/false value. + + Example: + \qml + Item { focus: true; clip: false } + \endqml + + \target basicqmlreal + \section1 real + + A \c real is a number - either a whole number like an \c int, or a fractional number + like 1.2 or -29.8. + + Example: + \qml + Item { width: 100.45; height: 150.82 } + \endqml + + \note In QML all reals are stored in single precision, \l {http://en.wikipedia.org/wiki/IEEE_754}{IEEE floating point} format. + + \target basicqmlstring + \section1 string + + A string is a free form text, like "Hello world!". + + Example: + \qml + Text { text: "Hello world!" } + \endqml + + \target basicqmlurl + \section1 url + + A URL is a resource locator, like a file name. It can be either absolute, like "http://qtsoftware.com", + or relative, like "pics/logo.png". A relative URL is resolved relative to the URL of the component where + the URL is converted from a JavaScript string expression to a url property value. + + Example: + \qml + Image { source: "pics/logo.png" } + \endqml + + \raw HTML + \endraw + + \target basicqmlcolor + \section1 color + + A \c color is most commonly specified as an \l {http://www.w3.org/TR/SVG/types.html#ColorKeywords}{SVG color name}. These names include colors like + "red", "green" and "lightsteelblue". + + If the color you want isn't part of this list, colors can also be specified + in hexidecimal triplets or quads that take the form \c "#RRGGBB" and + \c "#AARRGGBB" respectively. For example, the color red corresponds to a + triplet of \c "#FF0000" and a slightly transparent blue to a quad of + \c "#800000FF". + + Example: + \qml + Rectangle { color: "steelblue" } + Rectangle { color: "#FF0000" } + Rectangle { color: "#800000FF" } + \endqml + + \target basicqmlpoint + \section1 point + + A \c point is specified in \c "x,y" format. + + Example: + \qml + Widget { pos: "0,20" } + \endqml + + \target basicqmlsize + \section1 size + + A \c size is specified in \c "widthxheight" format. + + Example: + \qml + Widget { size: "150x50" } + \endqml + + \target basicqmlrectangle + \section1 rect + + A \c rect is specified in \c "x,y,widthxheight" format. + + Example: + \qml + Widget { geometry: "50,50,100x100" } + \endqml + + \target basicqmldate + \section1 date + + A \c date is specified in \c "YYYY-MM-DD" format. + + Example: + \qml + DatePicker { minDate: "2000-01-01"; maxDate: "2020-12-31" } + \endqml + + \target basicqmltime + \section1 time + + A \c time is specified in \c "hh:mm:ss" format. + + Example: + \qml + TimePicker { time: "14:22:15" } + \endqml + + \target basicqmlfont + \section1 font + + The \c font type has the following properties of a QFont: + \list + \o \c string font.family + \o \c bool font.bold + \o \c bool font.italic + \o \c bool font.underline + \o \c real font.pointSize + \o \c int font.pixelSize + \endlist + + Example: + \qml + Text { font.family: "Helvetica"; font.pointSize: 13; font.bold: true } + \endqml + + \target basicqmlaction + \section1 action + + The action type has all the properties of QAction, in particular: + \list + \o \c slot action.trigger - invoke the action + \o \c bool action.enabled - true if the action is enabled + \o \c string action.text - the text associated with the action + \endlist + + Actions are used like this: + + \qml + MouseRegion { onClicked: MyItem.myaction.trigger() } + State { name: "enabled"; when: MyItem.myaction.enabled == true } + Text { text: MyItem.someaction.text } + \endqml + + \target basicqmllist + \section1 list + + While not technically a basic type, QML also supports lists of object + types. When used from QML, the engine automatically appends each value to the + list. + + For example, the \l Item class has a children list property + that can be used like this: + \qml + Item { + children: [ + Item { id: Child1 }, + Rectangle { id: Child2 }, + Text { id: Child3 } + ] + } + \endqml + \c Child1, \c Child2 and \c Child3 will all be added to the children list + in the order in which they appear. +*/ diff --git a/doc/src/declarative/binding.qdoc b/doc/src/declarative/binding.qdoc new file mode 100644 index 0000000..7e8933f --- /dev/null +++ b/doc/src/declarative/binding.qdoc @@ -0,0 +1,110 @@ +/*! +\page binding.html +\title Data Binding in QML +\target binding + +Data binding provides a declarative way of specifying the data associated with objects, as well as the relationship between data of different objects. For example, you could bind the text of a label to the value of a slider: as the value of the slider changed, the label would be automatically updated with the new value. + +Bindings are created in QML when an expression is assigned to a property. For example, the following produces two rectangles of equal size (\c Rect2 is bound to the size of \c Rect1): +\code +Rectangle { id: Rect1; width: 100; height: 100 } +Rectangle { id: Rect2; width: Rect1.width; height: Rect1.height } +\endcode + +There is also a special \l Binding element, which is typically used to bind from the UI to the underlying UI model (see \l {Passing Data Between C++ and QML} for an example of this). The bindings above could be expressed using the \l Binding element as: + +\code +Binding { target: Rect2; property: "width"; value: Rect1.width } +Binding { target: Rect2; property: "height"; value: Rect1.height } +\endcode + +In addition to binding directly to a property, you can also bind to the results of expressions involving properties. For example: +\code +Text { text: contact.firstname + ' ' + contact.lastname } +Image { source: if (contact.gender == "female") {"pics/female.png"} else {"pics/male.png"} } +\endcode + +Relevant items can also be bound to the contents of a model - see \l ListView for an example of this. + +Data can be bound to C++ objects - see \l {QML/C++ Data Binding}. +*/ + +/*! +\page qtbinding.html +\target qtbinding +\title QML/C++ Data Binding + +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). + +Relevant items can also be bound to the contents of a Qt model. For example, ListView can make use of data from a QListModelInterface-derived model. (QListModelInterface is part of the next generation Model/View architecture being developed for Qt.) + + +\section1 Passing Data Between C++ and QML + +Data binding provides one method of data transfer between C++ and QML. + +For example, lets say you want to implement a slider in QML that changes the screen brightness of the device it is running on. You would start by declaring a brightness property on your QObject-derived class: +\code +class MyScreen : public QObject +{ + Q_OBJECT +public: + MyScreen(QObject *parent=0); + + Q_PROPERTY(int brightness READ brightness WRITE setBrightness NOTIFY brightnessChanged); + int brightness() const; + void setBrightness(int b); + ... + +signals: + void brightnessChanged(); + +private: + int m_brightness; +}; + +int brightness() const +{ + return m_brightness; +} + +void setBrightness(int b) +{ + if (b != m_brightness) { + m_brightness = b; + emit brightnessChanged(); + + //set device brightness + ... + } +} +\endcode + +\note One important thing to keep in mind is that the changed signal should only be emitted when there is a real change ( \c b \c != \c m_brightness ), or you may get an infinite loop. + +Next, make an instance of this class visible to the QML bind engine: +\code +QFxView *view = new QFxView; +view->setUrl("MyUI.qml"); + +MyScreen *screen = new MyScreen; +QmlContext *ctxt = view->rootContext(); +ctxt->setContextProperty("screen", screen); + +view->execute(); +\endcode + +\note Bindings must be made after setUrl() but before execute(). + +Finally, in QML you can make the appropriate bindings, so in \c "MyUI.qml": + +\code +Slider { value: screen.brightness } +Binding { target: screen; property: "brightness"; value: slider.value } +\endcode + +The \l QBindableMap class provides a convenient way to make data visible to the bind engine. + +*/ diff --git a/doc/src/declarative/cppitem.qdoc b/doc/src/declarative/cppitem.qdoc new file mode 100644 index 0000000..4543156 --- /dev/null +++ b/doc/src/declarative/cppitem.qdoc @@ -0,0 +1,129 @@ +/*! +\page cppitem.html +\target cppitem +\title C++ Components for QML + +\section1 Making a C++ object available in QML + +In QML, the item types and properties correspond to Qt objects and properties. Thus, any Qt object +can potentially be used as an item in QML. More specifically, to make an object available in QML, +it should: +\list +\o Be a subclass of QObject. +\o Provide a default constructor. +\o Declare Q_PROPERTYs. +\o Be registered via the QML_DECLARE_TYPE and QML_DEFINE_TYPE macros. +\endlist + +\section2 Declaring Q_PROPERTYs +\target properties + +Properties of QObject subclasses are available as properties in QML. +Like any QObject, these properties are defined by the Q_PROPERTY +macro in the header file. + +Properties should have a NOTIFY function if they can change dynamically and +if any useful response could be made to them changing in another object. Almost +all properties will thus need a NOTIFY function. + +\code + Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged); + qreal scale() const; + void setScale(qreal); + ... + signals: void scaleChanged(); +\endcode + +The property types currently supported by QML are: +\list +\o int +\o qreal +\o QString +\o QColor +\o QDate, QTime, and QDateTime +\o QSize and QSizeF +\o QPoint and QPointF +\o QRect and QRectF +\o QPixmap +\o QIcon +\o enums registered with Q_ENUMS +\o flags registered with Q_FLAGS +\o QVariant +\o QObject* (or subclass) +\endlist + +Custom property types that provide string-to-type conversion can be used as well, by: +\list +\o Registering them as a metatype (Q_DECLARE_METATYPE() and qRegisterMetaType()) +\o Registering a string-to-type convertor function (QML::addCustomStringConvertor()). +\endlist + +\section2 Registering your type +\target register + +In order for your type to be usable in QML, you must register it: + +\code +QML_DECLARE_TYPE(TypeName); +QML_DEFINE_TYPE(ModuleUri,ModuleMajorVersion,ModuleMinorVersionFrom,ModuleMinorVersionTo,QmlName,TypeName); +\endcode + +These macros make the C++ \e TypeName available from the declarative markup language under the name \e QmlName. +Of course there's nothing stopping you using the same name for both the C++ and the QML name! + +For example: +\code +QML_DECLARE_TYPE(MyCircle); +QML_DEFINE_TYPE(MyLib,1,0,5,Circle,MyCircle); +\endcode +would make the \e MyCircle class accessable though the \c Circle type in QML whenever MyLib 1.0 to 1.5 is imported. + + +\section1 Creating a new type of QML item in C++ + +You can create a new type of QML item by: +\list 1 +\o Creating a subclass of QFxItem, +\o Adding Q_PROPERTYs appropriate for your item (see \l {properties}{Properties}), +\o Reimplementing the relevant paint functions, +\o Registering the type with the QML_DECLARE_TYPE and QML_DEFINE_TYPE macros (see \l {register}{Register}). +\endlist + +\section2 Creating a subclass of QFxItem + +To add a new type, you first must add a new C++ class derived from QFxItem. +You may of course extend existing QFxItem subclasses. + +One existing subclass is QFxPainted, which provides +a simple cached-image painting model. + +\section2 Reimplementing paint functions + +\warning This section is out of date. Use the normal QGraphicsItem::paint function. + +Two alternative painters are available, offering +different levels of performance and functionality: +QPainter, GLPainter. + +You can choose to subclass QFxPainted rather than QFxItem, +and then implement the virtual method: + +\code + void paint(QPainter *painter); +\endcode + +This paints into an offscreen pixmap which is then painted to the display (transformed, +etc. as needed). The cost of this offscreen pixmap should be carefully considered, as +should the specific performance of the painting done in the paint function. + +If you require more control, subclass QFxItem instead. +QFxItem subclasses must implement both simple software canvas painting +and GL painting: +\list +\o \c QFxItem::paintContents(QPainter &) for the simple software canvas, +\o \c QFxItem::paintGLContents(GLPainter &) for OpenGL. +\endlist + +See the documentation of those functions for detailed subclassing notes. + +*/ diff --git a/doc/src/declarative/elements.qdoc b/doc/src/declarative/elements.qdoc new file mode 100644 index 0000000..bfaf4ab --- /dev/null +++ b/doc/src/declarative/elements.qdoc @@ -0,0 +1,157 @@ +/*! +\page elements.html +\target elements +\title QML Elements + +The following table lists the QML elements provided by the Qt Declarative module. + +\bold {Standard Qt Declarative Elements} + +\table 80% +\header +\o \bold {States} +\o \bold {Animation and Transitions} +\o \bold {Working with Data} +\o \bold {Utility} +\row + +\o +\list +\o \l State +\o \l PropertyChanges +\o \l ParentChange +\o \l StateChangeScript +\o \l AnchorChanges +\endlist + +\o +\list +\o \l PropertyAnimation +\o \l NumberAnimation +\o \l ColorAnimation +\o \l SequentialAnimation +\o \l ParallelAnimation +\o \l PauseAnimation +\o \l PropertyAction +\o \l ParentAction +\o \l ScriptAction +\o \l Transition +\o \l Follow +\o \l Behavior +\endlist + +\o +\list +\o \l Binding +\o \l ListModel +\o \l VisualItemModel +\o \l XmlListModel and XmlRole +\o \l SqlQuery, \l SqlConnection, and \l SqlBind +\o \l DateTimeFormatter +\o \l NumberFormatter +\endlist + +\o +\list +\o \l Script +\o \l Connection +\o \l Component +\o \l Timer +\endlist +\endtable + +\bold {QML Items} + +\table 80% +\header +\o \bold {Basic Visual Items} +\o \bold {Basic Interaction Items} +\o \bold {Widgets} +\o \bold {Utility} + +\row +\o +\list +\o \l Item +\o \l Rectangle +\o \l Image +\o \l BorderImage +\o \l Text +\o \l TextInput +\o \l TextEdit +\endlist + +\o +\list +\o \l MouseRegion +\o \l FocusScope +\o \l KeyProxy +\endlist + +\o +\list +\o \l Flickable +\o \l Flipable +\o \l WebView +\endlist + +\o +\list +\o \l Loader +\o \l Repeater +\o \l SystemPalette +\o \l ComponentInstance +\o \l GraphicsObjectContainer +\endlist + +\header +\o \bold {Views} +\o \bold {Positioners} +\o \bold {Transforms} +\o \bold {Effects} + +\row +\o + +\target xmlViews +\list +\o \l ListView +\o \l GridView +\o \l PathView + \list + \o \l Path + \list + \o \l PathLine + \o \l PathQuad + \o \l PathCubic + \o \l PathAttribute + \o \l PathPercent + \endlist + \endlist +\endlist + +\o +\list +\o \l Column +\o \l Row +\o \l Grid +\endlist + +\o +\list +\o \l Scale +\o \l Rotation +\endlist + +\o +\list +\o \l Particles + \list + \o \l ParticleMotionLinear + \o \l ParticleMotionGravity + \o \l ParticleMotionWander + \endlist +\endlist +\endtable + +*/ diff --git a/doc/src/declarative/examples.qdoc b/doc/src/declarative/examples.qdoc new file mode 100644 index 0000000..49a825a --- /dev/null +++ b/doc/src/declarative/examples.qdoc @@ -0,0 +1,30 @@ +/*! +\page qmlexamples.html +\target qmlexamples +\title QML Examples + +A \l {qmlviewer}{viewer} application is included that allows you to quickly explore many of the +examples. It has some useful options, revealed by: + +\code + bin/qmlviewer -help +\endcode + +There are several illustrative QML examples available. From your build +directory, + +\code + bin/qmlviewer $QT_SOURCE_DIR/demos/declarative/flickr/flickr.qml +\endcode + +Many other simple examples can be found under the \c examples/declarative sub +directory. Some can be run directly using the viewer like those above, and +others require you to build and run an executable. + +More sophisticated demos of large applications can be found under the \c demos/declarative +sub directory. These are intended to show more integrated functionality rather than +to be instructive on specific elements. + +Finally, check out the \l {tutorial} to learn a little more about writing your +own QML-based applications. +*/ diff --git a/doc/src/declarative/extending-examples.qdoc b/doc/src/declarative/extending-examples.qdoc new file mode 100644 index 0000000..17bef4e --- /dev/null +++ b/doc/src/declarative/extending-examples.qdoc @@ -0,0 +1,309 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\example declarative/extending/adding +\title Extending QML - Adding Types Example + +The Adding Types Example shows how to add a new element type, \c Person, to QML. +The \c Person type can be used from QML like this: + +\snippet examples/declarative/extending/adding/example.qml 0 + +\section1 Declare the Person class + +All QML elements map to C++ types. Here we declare a basic C++ Person class +with the two properties we want accessible on the QML type - name and shoeSize. +Although in this example we use the same name for the C++ class as the QML +element, the C++ class can be named differently, or appear in a namespace. + +\snippet examples/declarative/extending/adding/person.h 0 + +Following the class declaration, we include the QML_DECLARE_TYPE() macro. This +is necessary to declare the type to QML. It also includes the logic necessary +to expose the class to Qt's meta system - that is, it includes the +Q_DECLARE_METATYPE() functionality. + +\section1 Define the Person class + +\snippet examples/declarative/extending/adding/person.cpp 0 + +The Person class implementation is quite basic. The property accessors simply +return members of the object instance. + +The implementation must also include the QML_DEFINE_TYPE() macro. This macro +registers the Person class with QML as a type in the People library version 1.0, +and defines the mapping between the C++ and QML class names. + +\section1 Running the example + +The main.cpp file in the example includes a simple shell application that +loads and runs the QML snippet shown at the beginning of this page. +*/ + +/*! +\example declarative/extending/properties +\title Extending QML - Object and List Property Types Example + +This example builds on: +\list +\o \l {Extending QML - Adding Types Example} +\endlist + +The Object and List Property Types example shows how to add object and list +properties in QML. This example adds a BirthdayParty element that specifies +a birthday party, consisting of a celebrant and a list of guests. People are +specified using the People QML type built in the previous example. + +\snippet examples/declarative/extending/properties/example.qml 0 + +\section1 Declare the BirthdayParty + +The BirthdayParty class is declared like this: + +\snippet examples/declarative/extending/properties/birthdayparty.h 0 +\snippet examples/declarative/extending/properties/birthdayparty.h 1 +\snippet examples/declarative/extending/properties/birthdayparty.h 2 +\snippet examples/declarative/extending/properties/birthdayparty.h 3 + +The class contains a member to store the celebrant object, and also a +QmlConcreteList<Person *> member. + +In QML, the type of a list properties - and the guests property is a list of +people - are all of type QmlList<T *>*. QmlList is an abstract list interface +that allows a developer to react to QML accessing and modifying the contents of +the list. This is useful for implementing "virtual lists" or other advanced +scenarios, but can't be used directly for the common case of just wanting a +regular list of things. For this a concrete implementation, QmlConcreteList, is +provided and that is used here. + +\section2 Define the BirthdayParty + +The implementation of BirthdayParty property accessors is straight forward. + +\snippet examples/declarative/extending/properties/birthdayparty.cpp 0 + +\section1 Running the example + +The main.cpp file in the example includes a simple shell application that +loads and runs the QML snippet shown at the beginning of this page. +*/ + +/*! +\example declarative/extending/coercion +\title Extending QML - Inheritance and Coercion Example + +This example builds on: +\list +\o \l {Extending QML - Object and List Property Types Example} +\o \l {Extending QML - Adding Types Example} +\endlist + +The Inheritance and Coercion Example shows how to use base classes to assign +elements of more than one type to a property. It specializes the Person element +developed in the previous examples into two elements - a \c Boy and a \c Girl. + +\snippet examples/declarative/extending/coercion/example.qml 0 + +\section1 Declare Boy and Girl + +\snippet examples/declarative/extending/coercion/person.h 0 + +The Person class remains unaltered in this example and the Boy and Girl C++ +classes are trivial extensions of it. As an example, the inheritance used here +is a little contrived, but in real applications it is likely that the two +extensions would add additional properties or modify the Person classes +behavior. + +\section2 Define People as a base class + +The implementation of the People class itself has not changed since the the +previous example. However, as we have repurposed the People class as a common +base for Boy and Girl, we want to prevent it from being instantiated from QML +directly - an explicit Boy or Girl should be instantiated instead. + +\snippet examples/declarative/extending/coercion/person.cpp 0 + +While we want to disallow instantiating Person from within QML, it still needs +to be registered with the QML engine, so that it can be used as a property type +and other types can be coerced to it. To register a type, without defining a +named mapping into QML, we use the QML_DEFINE_NOCREATE_TYPE() macro instead of +the QML_DEFINE_TYPE() macro used previously. + +\section2 Define Boy and Girl + +The implementation of Boy and Girl are trivial. + +\snippet examples/declarative/extending/coercion/person.cpp 1 + +All that is necessary is to implement the constructor, and to register the types +and their QML name with the QML engine. + +\section1 Running the example + +The BirthdayParty element has not changed since the previous example. The +celebrant and guests property still use the People type. + +\snippet examples/declarative/extending/coercion/birthdayparty.h 0 + +However, as all three types, Person, Boy and Girl, have been registered with the +QML system, on assignment QML automatically (and type-safely) converts the Boy +and Girl objects into a Person. + +The main.cpp file in the example includes a simple shell application that +loads and runs the QML snippet shown at the beginning of this page. +*/ + +/*! +\example declarative/extending/default +\title Extending QML - Default Property Example + +This example builds on: +\list +\o \l {Extending QML - Inheritance and Coercion Example} +\o \l {Extending QML - Object and List Property Types Example} +\o \l {Extending QML - Adding Types Example} +\endlist + +The Default Property Example is a minor modification of the +\l {Extending QML - Inheritance and Coercion Example} that simplifies the +specification of a BirthdayParty through the use of a default property. + +\snippet examples/declarative/extending/default/example.qml 0 + +\section1 Declaring the BirthdayParty class + +The only difference between this example and the last, is the addition of the +\c DefaultProperty class info annotation. + +\snippet examples/declarative/extending/default/birthdayparty.h 0 + +The default property specifies the property to assign to whenever an explicit +property is not specified, in the case of the BirthdayParty element the guest +property. It is purely a syntactic simplification, the behavior is identical +to specifying the property by name, but it can add a more natural feel in many +situations. The default property must be either an object or list property. + +\section1 Running the example + +The main.cpp file in the example includes a simple shell application that +loads and runs the QML snippet shown at the beginning of this page. +*/ + +/*! +\example declarative/extending/grouped +\title Extending QML - Grouped Properties Example + +This example builds on: +\list +\o \l {Extending QML - Default Property Example} +\o \l {Extending QML - Inheritance and Coercion Example} +\o \l {Extending QML - Object and List Property Types Example} +\o \l {Extending QML - Adding Types Example} +\endlist + +*/ + +/*! +\example declarative/extending/grouped +\title Extending QML - Attached Properties Example + +This example builds on: +\list +\o \l {Extending QML - Grouped Properties Example} +\o \l {Extending QML - Default Property Example} +\o \l {Extending QML - Inheritance and Coercion Example} +\o \l {Extending QML - Object and List Property Types Example} +\o \l {Extending QML - Adding Types Example} +\endlist + +*/ + +/*! +\example declarative/extending/signal +\title Extending QML - Signal Support Example + +This example builds on: +\list +\o \l {Extending QML - Attached Properties Example} +\o \l {Extending QML - Grouped Properties Example} +\o \l {Extending QML - Default Property Example} +\o \l {Extending QML - Inheritance and Coercion Example} +\o \l {Extending QML - Object and List Property Types Example} +\o \l {Extending QML - Adding Types Example} +\endlist + +*/ + +/*! +\example declarative/extending/valuesource +\title Extending QML - Property Value Source Example + +This example builds on: +\list +\o \l {Extending QML - Signal Support Example} +\o \l {Extending QML - Attached Properties Example} +\o \l {Extending QML - Grouped Properties Example} +\o \l {Extending QML - Default Property Example} +\o \l {Extending QML - Inheritance and Coercion Example} +\o \l {Extending QML - Object and List Property Types Example} +\o \l {Extending QML - Adding Types Example} +\endlist + +*/ + +/*! +\example declarative/extending/binding +\title Extending QML - Binding Example + +This example builds on: +\list +\o \l {Extending QML - Property Value Source Example} +\o \l {Extending QML - Signal Support Example} +\o \l {Extending QML - Attached Properties Example} +\o \l {Extending QML - Grouped Properties Example} +\o \l {Extending QML - Default Property Example} +\o \l {Extending QML - Inheritance and Coercion Example} +\o \l {Extending QML - Object and List Property Types Example} +\o \l {Extending QML - Adding Types Example} +\endlist + +*/ diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc new file mode 100644 index 0000000..3235435 --- /dev/null +++ b/doc/src/declarative/extending.qdoc @@ -0,0 +1,882 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\page qml-extending.html +\title Extending QML + +The QML syntax declaratively describes how to construct an in memory object +tree. In Qt, QML is mainly used to describe a visual scene graph, but it is +not conceptually limited to this: the QML format is an abstract description of +any object tree. All the QML element types included in Qt are implemented using +the C++ extension mechanisms describe on this page. Programmers can use these +APIs to add new types that interact with the existing Qt types, or to repurpose +QML for their own independent use. + +\tableofcontents + +\section1 Adding Types + +\snippet examples/declarative/extending/adding/example.qml 0 + +The QML snippet shown above instantiates one \c Person instance and sets +the name and shoeSize properties on it. Everything in QML ultimately comes down +to either instantiating an object instance, or assigning a property a value. +QML relies heavily on Qt's meta object system and can only instantiate classes +that derive from QObject. + +The QML engine has no intrinsic knowledge of any class types. Instead the +programmer must define the C++ types, and their corresponding QML name. + +Custom C++ types are made available to QML using these two macros: + +\quotation +\code +#define QML_DECLARE_TYPE(T) +#define QML_DEFINE_TYPE(URI,VMAJ,VFROM,VTO,QmlName,T) +\endcode + +Register the C++ type \a T with the QML system, and make it available in QML +under the name \a QmlName in library URI version VMAJ.VFROM to VMAJ.VTO. +\a T and \a QmlName may be the same. + +Generally the QML_DECLARE_TYPE() macro should be included immediately following +the type declaration (usually in its header file), and the QML_DEFINE_TYPE() +macro in the implementation file. QML_DEFINE_TYPE() must not be present in +a header file. + +Type \a T must be a concrete type that inherits QObject and has a default +constructor. +\endquotation + +Once registered, all of the \l {Qt's Property System}{properties} of a supported +type are available for use within QML. QML has intrinsic support for properties +of these types: + +\list +\o bool +\o unsigned int, int +\o float, double, qreal +\o QString +\o QUrl +\o QColor +\o QDate, QTime, QDateTime +\o QPoint, QPointF +\o QSize, QSizeF +\o QRect, QRectF +\o QVariant +\endlist + +QML is typesafe. Attempting to assign an invalid value to a property will +generate an error. For example, assuming the name property of the \c Person +element had a type of QString, this would cause an error: + +\code +Person { + // Will NOT work + name: 12 +} +\endcode + +\l {Extending QML - Adding Types Example} shows the complete code used to create +the \c Person type. + +\section1 Object and List Property Types + +\snippet examples/declarative/extending/properties/example.qml 0 + +The QML snippet shown above assigns a \c Person object to the \c BirthdayParty's +celebrant property, and assigns three \c Person objects to the guests property. + +QML can set properties of types that are more complex than basic intrinsics like +integers and strings. Properties can also be object pointers, Qt interface +pointers, lists of object points, and lists of Qt interface pointers. As QML +is typesafe it ensures that only valid types are assigned to these properties, +just like it does for primitive types. + +Properties that are pointers to objects or Qt interfaces are declared with the +Q_PROPERTY() macro, just like other properties. The celebrant property +declaration looks like this: + +\snippet examples/declarative/extending/properties/birthdayparty.h 1 + +As long as the property type, in this case Person, is registered with QML the +property can be assigned. + +QML also supports assigning Qt interfaces. To assign to a property whose type +is a Qt interface pointer, the interface must also be registered with QML. As +they cannot be instantiated directly, registering a Qt interface is different +from registering a new QML type. The following macros are used instead: + +\quotation +\code + #define QML_DECLARE_INTERFACE(T) + #define QML_DEFINE_INTERFACE(T) +\endcode + +Register the C++ interface \a T with the QML system. + +Generally the QML_DECLARE_INTERFACE() macro should be included immediately +following the interface declaration (usually in its header file), and the +QML_DEFINE_INTERFACE() macro in an implementation file. QML_DEFINE_INTERFACE() +must not be present in a header file. + +Following registration, QML can coerce objects that implement this interface +for assignment to appropriately typed properties. +\endquotation + +The guests property is a list of \c Person objects. Properties that are lists +of objects or Qt interfaces are also declared with the Q_PROPERTY() macro, just +like other properties. List properties must have the type \c {QmlList<T *>*}. +As with object properties, the type \a T must be registered with QML. + +The guest property declaration looks like this: + +\snippet examples/declarative/extending/properties/birthdayparty.h 2 + +\l {Extending QML - Object and List Property Types Example} shows the complete +code used to create the \c BirthdayParty type. + +\section1 Inheritance and Coercion + +\snippet examples/declarative/extending/coercion/example.qml 0 + +The QML snippet shown above assigns a \c Boy object to the \c BirthdayParty's +celebrant property, and assigns three other objects to the guests property. + +QML supports C++ inheritance heirarchies and can freely coerce between known, +valid object types. This enables the creation of common base classes that allow +the assignment of specialized classes to object or list properties. In the +snippet shown, both the celebrant and the guests properties retain the Person +type used in the previous section, but the assignment is valid as both the Boy +and Girl objects inherit from Person. + +To assign to a property, the property's type must have been registered with QML. +Both the QML_DEFINE_TYPE() and QML_DEFINE_INTERFACE() macros already shown can +be used to register a type with QML. Additionally, if a type that acts purely +as a base class that cannot be instantiated from QML needs to be +registered these macros can be used: + +\quotation +\code + #define QML_DECLARE_TYPE(T) + #define QML_DEFINE_NOCREATE_TYPE(T) +\endcode + +Register the C++ type \a T with the QML system. QML_DEFINE_NOCREATE_TYPE() +differs from QML_DEFINE_TYPE() in that it does not define a mapping between the +C++ class and a QML element name, so the type is not instantiable from QML, but +it is available for type coercion. + +Generally the QML_DECLARE_TYPE() macro should be included immediately following +the type declaration (usually in its header file), and the +QML_DEFINE_NOCREATE_TYPE() macro in the implementation file. +QML_DEFINE_NOCREATE_TYPE() must not be present in a header file. + +Type \a T must inherit QObject, but there are no restrictions on whether it is +concrete or the signature of its constructor. +\endquotation + +QML will automatically coerce C++ types when assigning to either an object +property, or to a list property. Only if coercion fails does an assignment +error occur. + +\l {Extending QML - Inheritance and Coercion Example} shows the complete +code used to create the \c Boy and \c Girl types. + +\section1 Default Property + +\snippet examples/declarative/extending/default/example.qml 0 + +The QML snippet shown above assigns a collection of objects to the +\c BirthdayParty's default property. + +The default property is a syntactic convenience that allows a type designer to +specify a single property as the type's default. The default property is +assigned to whenever no explicit property is specified. As a convenience, it is +behaviorally identical to assigning the default property explicitly by name. + +From C++, type designers mark the default property using a Q_CLASSINFO() +annotation: + +\quotation +\code +Q_CLASSINFO("DefaultProperty", "property") +\endcode + +Mark \a property as the class's default property. \a property must be either +an object property, or a list property. + +A default property is optional. A derived class inherits its base class's +default property, but may override it in its own declaration. \a property can +refer to a property declared in the class itself, or a property inherited from a +base class. +\endquotation + +\l {Extending QML - Default Property Example} shows the complete code used to +specify a default property. + +\section1 Grouped Properties + +\snippet examples/declarative/extending/grouped/example.qml 1 + +The QML snippet shown above assigns a number properties to the \c Boy object, +including four properties using the grouped property syntax. + +Grouped properties collect similar properties together into a single named +block. Grouped properties can be used to present a nicer API to developers, and +may also simplify the implementation of common property collections across +different types through implementation reuse. + +A grouped property block is implemented as a read-only object property. The +shoe property shown is declared like this: + +\snippet examples/declarative/extending/grouped/person.h 1 + +The ShoeDescription type declares the properties available to the grouped +property block - in this case the size, color, brand and price properties. + +Grouped property blocks may declared and accessed be recusively. + +\l {Extending QML - Grouped Properties Example} shows the complete code used to +implement the \c shoe property grouping. + +\section1 Attached Properties + +\snippet examples/declarative/extending/attached/example.qml 1 + +The QML snippet shown above assigns the rsvp property using the attached +property syntax. + +Attached properties allow unrelated types to annotate other types with some +additional properties, generally for their own use. Attached properties are +identified through the use of the attacher type name, in the case shown +\c BirthdayParty, as a suffix to the property name. + +In the example shown, \c BirthdayParty is called the attaching type, and the +Box instance the attachee object instance. + +For the attaching type, an attached property block is implemented as a new +QObject derived type, called the attachment object. The properties on the +attachment object are those that become available for use as the attached +property block. + +Any QML type can become an attaching type by declaring the +\c qmlAttachedProperties() public function: + +\quotation +\code +static AttachedPropertiesType *qmlAttachedProperties(QObject *object) +\endcode +Return an attachment object, of type \a AttachedPropertiesType, for the +attachee \a object instance. It is customary, though not strictly required, for +the attachment object to be parented to \a object to prevent memory leaks. + +\a AttachedPropertiesType must be a QObject derived type. The properties on +this type will be accessible through the attached properties syntax. + +This method will be called at most once for each attachee object instance. The +QML engine will cache the returned instance pointer for subsequent attached +property accesses. Consequently the attachment object may not be deleted until +\a object is destroyed. +\endquotation + +Conceptually, attached properties are a \e type exporting a set of additional +properties that can be set on \e any other object instance. Attached properties +cannot be limited to only attaching to a sub-set of object instances, although +their effect may be so limited. + +For example, a common usage scenario is for a type to enhance the properties +available to its children in order to gather instance specific data. Here we +add a rsvp field to all the guests coming to a birthday party: +\code +BirthdayParty { + Boy { BirthdayParty.rsvp: "2009-06-01" } +} +\endcode +However, as a type cannot limit the instances to which the attachment object +must attach, the following is also allowed, even though adding a birthday party +rsvp in this context will have no effect. +\code +GraduationParty { + Boy { BirthdayParty.rsvp: "2009-06-01" } +} +\endcode + +From C++, including the attaching type implementation, the attachment object for +an instance can be accessed using the following method: + +\quotation +\code +template<typename T> +QObject *qmlAttachedPropertiesObject<T>(QObject *attachee, bool create = true); +\endcode +Returns the attachment object attached to \a attachee by the attaching type +\a T. If type \a T is not a valid attaching type, this method always returns 0. + +If \a create is true, a valid attachment object will always be returned, +creating it if it does not already exist. If \a create is false, the attachment +object will only be returned if it has previously been created. +\endquotation + +\l {Extending QML - Attached Properties Example} shows the complete code used to +implement the rsvp attached property. + +\section1 Signal Support + +\snippet examples/declarative/extending/signal/example.qml 0 +\snippet examples/declarative/extending/signal/example.qml 1 + +The QML snippet shown above associates the evaluation of a ECMAScript expression +with the emission of a Qt signal. + +All Qt signals on a registered class become available as special "signal +propeties" within QML to which the user can assign a single ECMAScript +expression. The signal property's name is a transformed version of the Qt +signal name: "on" is prepended, and the first letter of the signal name upper +cased. For example, the signal used in the example above has the following +C++ signature: + +\snippet examples/declarative/extending/signal/birthdayparty.h 0 + +In classes with multiple signals with the same name, only the final signal +is accessible as a signal property. Although QML provides an element, +\l Connection, for accessing the other signals it is less elegant. For the best +QML API, class developers should avoid overloading signal names. + +Signal parameters become accessible by name to the assigned script. An +unnamed parameter cannot be accessed, so care should be taken to name all the +signal parameters in the C++ class declaration. The intrinsic types +listed in \l {Adding Types}, as well registered object types are permitted as +signal parameter types. Using other types is not an error, but the parameter +value will not be accessible from script. + +\l {Extending QML - Signal Support Example} shows the complete code used to +implement the onPartyStarted signal property. + +\section1 Property Value Sources + +\snippet examples/declarative/extending/valuesource/example.qml 0 +\snippet examples/declarative/extending/valuesource/example.qml 1 + +The QML snippet shown above assigns a property value to the speaker property. +A property value source generates a value for a property that changes over time. + +Property value sources are most commonly used to do animation. Rather than +constructing an animation object and manually setting the animation's "target" +property, a property value source can be assigned directly to a property of any +type and automatically set up this association. + +The example shown here is rather contrived: the speaker property of the +BirthdayParty object is a string that is printed every time it is assigned and +the HappyBirthday value source generates the lyrics of the song +"Happy Birthday". + +\snippet examples/declarative/extending/valuesource/birthdayparty.h 0 + +Normally, assigning an object to a string property would not be allowed. In +the case of a property value source, rather than assigning the object instance +itself, the QML engine sets up an association between the value source and +the property. + +Property value sources are special types that derive from the +QmlPropertyValueSource base class. This base class contains a single method, +QmlPropertyValueSource::setTarget(), that the QML engine invokes when +associating the property value source with a property. The relevant part of +the HappyBirthday type declaration looks like this: + +\snippet examples/declarative/extending/valuesource/happybirthday.h 0 +\snippet examples/declarative/extending/valuesource/happybirthday.h 1 +\snippet examples/declarative/extending/valuesource/happybirthday.h 2 + +In all other respects, property value sources are regular QML types. They must +be registered with the QML engine using the same macros as other types, and can +contain properties, signals and methods just like other types. + +When a property value source object is assigned to a property, QML first tries +to assign it normally, as though it were a regular QML type. Only if this +assignment fails does the engine call the setTarget() method. This allows +the type to also be used in contexts other than just as a value source. + +\l {Extending QML - Property Value Source Example} shows the complete code used +implement the HappyBirthday property value source. + +\section1 Property Binding + +\snippet examples/declarative/extending/binding/example.qml 0 +\snippet examples/declarative/extending/binding/example.qml 1 + +The QML snippet shown above uses a property binding to ensure the +HappyBirthday's name property remains up to date with the celebrant. + +Property binding is a core feature of QML. In addition to assigning literal +values, property bindings allow the developer to assign an arbitrarily complex +ECMAScript expression that may include dependencies on other property values. +Whenever the expression's result changes - through a change in one of its +constituent values - the expression is automatically reevaluated and +the new result assigned to the property. + +All properties on custom types automatically support property binding. However, +for binding to work correctly, QML must be able to reliably determine when a +property has changed so that it knows to reevaluate any bindings that depend on +the property's value. QML relies on the presence of a +\c {Qt's Property System}{NOTIFY signal} for this determination. + +Here is the celebrant property declaration: + +\snippet examples/declarative/extending/binding/birthdayparty.h 0 + +The NOTIFY attribute is followed by a signal name. It is the responsibility of +the class implementer to ensure that whenever the property's value changes, the +NOTIFY signal is emitted. The signature of the NOTIFY signal is not important to QML. + +To prevent loops or excessive evaluation, developers should ensure that the +signal is only emitted whenever the property's value is actually changed. If +a property, or group of properties, is infrequently used it is permitted to use +the same NOTIFY signal for several properties. This should be done with care to +ensure that performance doesn't suffer. + +To keep QML reliable, if a property does not have a NOTIFY signal, it cannot be +used in a binding expression. However, the property can still be assigned +a binding as QML does not need to monitor the property for change in that +scenario. + +Consider a custom type, \c TestElement, that has two properties, "a" and "b". +Property "a" does not have a NOTIFY signal, and property "b" does have a NOTIFY +signal. + +\code +TestElement { + // This is OK + a: b +} +TestElement { + // Will NOT work + b: a +} +\endcode + +The presence of a NOTIFY signal does incur a small overhead. There are cases +where a property's value is set at object construction time, and does not +subsequently change. The most common case of this is when a type uses +\l {Grouped Properties}, and the grouped property object is allocated once, and +only freed when the object is deleted. In these cases, the CONSTANT attribute +may be added to the property declaration instead of a NOTIFY signal. + +\snippet examples/declarative/extending/binding/person.h 0 + +Extreme care must be taken here or applications using your type may misbehave. +The CONSTANT attribute should only be used for properties whose value is set, +and finalized, only in the class constructor. All other properties that want +to be used in bindings should have a NOTIFY signal instead. + +\l {Extending QML - Binding Example} shows the BirthdayParty example updated to +include NOTIFY signals for use in binding. + +\section1 Extension Objects + +\snippet examples/declarative/extending/extended/example.qml 0 + +The QML snippet shown above adds a new property to an existing C++ type without +modifying its source code. + +When integrating existing classes and technology into QML, their APIs will often +need to be tweaked to fit better into the declarative environment. Although +the best results are usually obtained by modifying the original classes +directly, if this is either not possible or is complicated by some other +concerns extension objects allow limited extension possibilities without +direct modifications. + +Extension objects can only add properties. + +\section1 Optimization + +*/ + + +/*! +\page qml-extending-types.html +\title Extending types from QML + +Many of the elements available for use in QML are implemented in +\l {QML for C++ Programmers}{C++}. These types are know as "core types". QML +allows programmers to build new, fully functional elements without using C++. +Existing core types can be extended, and new types defined entirely in the QML +language. + +\tableofcontents + +\section1 Adding new properties + +New properties can be added to an existing type. These new properties are +available for use within QML, and also appear as regular Qt properties on the +C++ object, accessible through the regular property access mechanisms. + +Like all properties in QML, custom properties are typed. The type is used to +define the property's behavior, and also determines the C++ type of the created +Qt property. The following table shows the list of types available when +declaring a new property, and the corresponding C++ type. + +\table +\header \o QML Type Name \o C++ Type Name +\row \o int \o int +\row \o bool \o bool +\row \o double \o double +\row \o real \o double +\row \o string \o QString +\row \o url \o QUrl +\row \o color \o QColor +\row \o date \o QDate +\row \o var \o QVariant +\row \o variant \o QVariant +\endtable + +QML supports two methods for adding a new property to a type - a new property +definition, and a property alias. + +\section2 Property definitions + +Property definitions add a new property to an existing type. The storage of the +property is managed by QML. The defined property may be read, written and bound +to and from. + +The syntax for defining a new property is: +\code + [default] property <type> <name>[: defaultValue] +\endcode + +This declaration may appear anywhere within a type body, but it is customary to +include it at the top. Attempting to declare two properties with the same name +in the same type block is an error. However, a new property may reuse the name +of an existing property on the type. This should be done with caution, as the +existing property will be hidden, and become inaccessible. + +The <type> must be one of the QML type names shown in the above table. +Additionally, an optional default value of the property can be provided. The +default value is a convenient shortcut, but is behaviorally identical to doing +it in two steps, like this: + +\code + // Use default value + property int myProperty: 10 + + // Longer, but behaviorally identical + property int myProperty + myProperty: 10 +\endcode + +If specified, the optional "default" attribute marks the new property as the +types default property, overriding any existing default property. Using the +default attribute twice in the same type block is an error. + +The following example shows how to declare a new "innerColor" property that +controls the color of the inner rectangle. + +\code + Rectangle { + property color innerColor: "black" + + color: "red"; width: 100; height: 100 + Rectangle { + anchors.centerIn: parent + width: parent.width - 10 + height: parent.height - 10 + color: innerColor + } + } +\endcode + +\section2 Property aliases + +Property aliases are a more advanced form of property declaration. Unlike a +property definition, that allocates a new, unique storage space for the +property, a property alias connects the newly declared property (called the +aliasing property) to an existing property (the aliased property). Read +operations on the aliasing property act as read operations on the aliased +property, and write operations on the aliasing property as write operations on +the aliased property. + +A property alias declaration looks a lot like a property definition: +\code + [default] property alias <name>: <alias reference> +\endcode + +As the aliasing property has the same type as the aliased property, an explicit +type is omitted, and the special "alias" keyword is used. Instead of a default +value, a property alias includes a compulsary alias reference. The alias +reference is used to locate the aliased property. While similar to a property +binding, the alias reference syntax is highly restricted. + +An alias reference takes the form +\code + <Id>.<property> +\endcode +where <Id> must refer to an object id within the same component as the type +declaring the alias, and <property> refers to a property on this object. The +alias reference syntax may become more flexibly in future releases. + +Here is the property definition example rewritten to use property aliases. +\code +Rectangle { + property alias innerColor: InnerRect.color + + color: "red"; width: 100; height: 100 + Rectangle { + id: InnerRect + anchors.centerIn: parent + width: parent.width - 10 + height: parent.height - 10 + color: "black" + } +} +\endcode + +Aliases are most useful when \l {Defining new Components}. Consequently +they have several apparent limitations that only make sense in this context. + +Aliases are only activated once the component specifying them is completed. The +most obvious consequence of this is that the component itself cannot generally +use the aliased property directly. For example, this will not work: + +\code + // Does NOT work + property alias innerColor: InnerRect.color + innerColor: "black" +\endcode + +This behavior is required to allow type developers to redefine the behavior +of existing property names while continuing to use the existing behavior within +the type they are building, something that is not possible with property +definitions. In the example used so far, this could allows the developer to fix +the external rectangle's color as "red" and redefine the "color" property to +refer to the inner rectangle, like this: + +\code +Rectangle { + property alias color: InnerRect.color + + color: "red"; width: 100; height: 100 + Rectangle { + id: InnerRect + anchors.centerIn: parent + width: parent.width - 10 + height: parent.height - 10 + color: "black" + } +} +\endcode + +Users of this type would not be able to affect the color of the red rectangle, +but would find using the "color" property, rather than the strange new +"innerColor" property, much more familiar. + +A second, much less significant, consequence of the delayed activation of +aliases is that an alias reference cannot refer to another aliasing property +declared within the same component. This will not work: + +\code + // Does NOT work + id: Root + property alias innerColor: InnerRect.color + property alias innerColor2: Root.innerColor +\endcode + +From outside the component, aliasing properties appear as regular Qt properties +and consequently can be used in alias references. + +\section1 Adding new signals + +New signals can be added to an existing type. These new signals are available +for use within QML, and also appear as regular Qt signals on the C++ object that +can be used in Qt signal/slot connections. + +The syntax for defining a new signal is: +\code +signal <name>[([<type> <parameter name>[, ...]])] +\endcode + +This declaration may appear anywhere within a type body, but it is customary to +include it at the top. Attempting to declare two signals or methods with the +same name in the same type block is an error. However, a new signal may reuse +the name of an existing signal on the type. This should be done with caution, +as the existing signal may be hidden and become inaccessible. + +The options for parameter types are the same as for property types (see +\l {Adding new properties}. If this signal has no parameters, the parameter +list may be omitted entirely. + +Here are three examples of signal declarations: +\code + Item { + signal clicked + signal hovered() + signal performAction(string action, var actionArgument) + } +\endcode + +\section1 Adding new methods + +New methods can be added to an existing type. These new methods are available +for use within QML, and also appear as regular Qt slots on the C++ object that +can be used in Qt signal/slot connections. + +\code +function <name>([<parameter name>[, ...]]) { <body> } +\endcode + +This declaration may appear anywhere within a type body, but it is customary to +include it at the top. Attempting to declare two methods or signals with the +same name in the same type block is an error. However, a new method may reuse +the name of an existing method on the type. This should be done with caution, +as the existing method may be hidden and become inaccessible. + +Methods parameters are not typed. In C++ these parameters are of type QVariant. +The body of the method is written in JavaScript and may access the parameters by +name. + +This example adds a new method that behaves like a child: +\code +Item { + function say(text) { + print("You said " + text); + } +} +\endcode + +\section1 Defining new Components + +A component is a reusable type with a well-defined interface built entirely in +QML. Components appear as regular QML elements, and can be used interchangably +with core types. Components allow developers to create new types to be reused +in other projects without the use of C++. Components can also help to reduce +duplication inside one project by limiting the need for large numbers of +copy-and-pasted blocks. + +Any snippet of QML code can become a component, just by placing it in the file +"<Name>.qml" where <Name> is the new element name, and begins with an uppercase +letter. These QML files automatically become available as new QML element types +to other QML components and applications in the same directory. + +For example, here we show how a component named "Box" is defined and used +multiple times by an application. + +\table +\row +\o application.qml +\code +Rectangle { + width: 100; height: 400; + Box { x: 0; y: 0 } + Box { x: 0; y: 150 } + Box { x: 0; y: 300 } +} +\endcode +\o Box.qml +\code +Rectangle { + width: 100; height: 100; + color: "blue" +} +\endcode +\endtable + +Components may be collected into \l {Modules} that gives the +developer more freedom than just putting files in the same directory. + +\section2 Building reusable components + +A component type built to be reused by others must have a well defined +interface. In QML, an interface consists of a defined collection of +properties, signals and methods. Users of a component have access to all the +properties, signals and methods defined on the root element of the component. + +In the component example above, the root element of the "Box" component is a +Rect. As the Rect type has a "color" property, this property is accessible to +users of the Box component. For example, the application.qml can be modified +to show three different colored boxes like this: +\code +Rectangle { + width: 100; height: 400; + Box { x: 0; y: 0; color: "red"; } + Box { x: 0; y: 150; color: "yellow"; } + Box { x: 0; y: 300; color: "green"; } +} +\endcode + +As expected, adding additional properties to the root element of Box, makes them +available externally. Here we add a "text" property: + +\table +\row +\o application.qml +\code +Rectangle { + width: 100; height: 400; + Box { x: 0; y: 0; color: "red"; text: "stop" } + Box { x: 0; y: 150; color: "yellow"; text: "slow" } + Box { x: 0; y: 300; color: "green"; text: "go" } +} +\endcode +\o Box.qml +\code +Rectangle { + property alias text: MyText.text + width: 100; height: 100; + color: "blue" + Text { + id: MyText + anchors.centerIn: parent + } +} +\endcode +\endtable + +Methods and signals may be added in the same way. + +As all external methods, signals and properties are accessible to external +users, developers should ensure that setting these properties does not have +any undesirable side-effects. For most resiliance, root level properties should +only be used for literal default values. When a root level property must be +used inside the component - such as the children property - property aliases +can be used to redirect this property to a "safe" location for external users. +Try to think of the root level properties as being "owned" by the components +user, rather than the component itself. +*/ diff --git a/doc/src/declarative/focus.qdoc b/doc/src/declarative/focus.qdoc new file mode 100644 index 0000000..7c293ee --- /dev/null +++ b/doc/src/declarative/focus.qdoc @@ -0,0 +1,262 @@ +/*! +\target qmlfocus +\page qmlfocus.html +\title Keyboard Focus in QML + +When a key is pressed or released, a key event is generated and delivered to the +focused QML \l Item. To facilitate the construction of reusable components +and to address some of the cases unique to fluid user interfaces, the QML items add a +\e scope based extension to Qt's traditional keyboard focus model. + +\section1 Key Handling Overview + +When the user presses or releases a key, the following occurs: +\list 1 +\o Qt receives the key action and generates a key event. +\o If the Qt widget containing the \l QFxView has focus, the key event is delivered to it. Otherwise, regular Qt key handling continues. +\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 {Rect} 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}. + +\code +Item { + KeyActions { + keyA: "print('Key A was pressed')" + Rectangle {} + } +} +\endcode + +\o If the root \l Item is reached, the key event is \l {QEvent::ignore()}{ignored} and regular Qt key handling continues. + +\endlist + +\section1 Querying the Active Focus Item + +Whether or not an \l Item has \e {active focus} can be queried through the +read-only property \c {Item::activeFocus}. For example, here we have a \l Text +element whose text is determined by whether or not it has \e {active focus}. + +\code +Text { + text: activeFocus ? "I have active focus!" : "I do not have active focus" +} +\endcode + +\section1 Acquiring Focus and Focus Scopes + +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. + +\table +\row +\o \code + Rectangle { + color: "lightsteelblue"; width: 240; height: 25 + Text { id: MyText } + KeyActions { + focus: true + keyA: "MyText.text = 'Key A was pressed'" + keyB: "MyText.text = 'Key B was pressed'" + keyC: "MyText.text = 'Key C was pressed'" + } + } +\endcode +\o \image declarative-qmlfocus1.png +\endtable + +However, were the above example to be used as a self-contained component, this +simple use of the \c {Item::focus} property is no longer sufficient. The left +hand side of the following table shows what we would like to be able to write. +Here we create two instances of our previously defined component, and set the +second one to have focus. The intention is that when the \e A, \e B, or \e C +keys are pressed, the second of the two components receives the event and +reponds accordingly. + +\table +\row +\o \code +Rectangle { + color: "red"; width: 240; height: 55 + MyWidget {} + MyWidget { y: 30; focus: true } +} +\endcode +\o \code +Rectangle { + color: "red"; width: 240; height: 55 + Rectangle { + color: "lightsteelblue"; width: 240; height: 25 + Text { id: MyText } + KeyActions { + focus: true + keyA: "MyText.text = 'Key A was pressed'" + keyB: "MyText.text = 'Key B was pressed'" + keyC: "MyText.text = 'Key C was pressed'" + } + } + Rectangle { + y: 30; focus: true + color: "lightsteelblue"; width: 240; height: 25 + Text { id: MyText } + KeyActions { + focus: true + keyA: "MyText.text = 'Key A was pressed'" + keyB: "MyText.text = 'Key B was pressed'" + keyC: "MyText.text = 'Key C was pressed'" + } + } +} +\endcode +\endtable + +The right hand side of the example shows the expanded code - the equivalent QML +without the use of the component \c {MyWidget}. From this, the problem is +evident - there are no less than three elements that have the \c {Item::focus} +property set to true. Ultimately only one element can have focus, and the +system has to decide which on. In this case the first appearance of the +\c {Item::focus} property being set to true on line 4 is selected, and the value +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 +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 +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 +of code knows everything about the other, which is exactly how it should be. + +To solve this problem - allowing components to care about what they know about +and ignore everything else - the QML items introduce a concept known as a +\e {focus scope}. For existing Qt users, a \e {focus scope} is like an +automatic focus proxy. A \e {focus scope} is created using the \l FocusScope +element. + +In the next example, a \l FocusScope is added to the component, and the visual +result shown. + +\table +\row +\o \code +FocusScope { + width: 240; height: 25 + Rectangle { + color: "lightsteelblue"; width: 240; height: 25 + Text { id: MyText } + KeyActions { + focus: true + keyA: "MyText.text = 'Key A was pressed'" + keyB: "MyText.text = 'Key B was pressed'" + keyC: "MyText.text = 'Key C was pressed'" + } + } +} +\endcode +\o \image declarative-qmlfocus2.png +\endtable + +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 +also a \l FocusScope, the proxying behaviour continues. Both the +\e {focus scope} and the sub-focused item will have \c {Item::activeFocus} set. +\endlist + +So far the example has the second component statically selected. It is trivial +now to extend this component to make it clickable, and add it to the original +application. We still set a one of the widgets as focused by default, but from +then on clicking the either one gives it focus. + +\table +\row +\o \code +Rectangle { + color: "red"; width: 240; height: 55 + MyClickableWidget {} + MyClickableWidget { y: 30; focus: true } +} +\endcode +\o \code +FocusScope { + id: Page; width: 240; height: 25 + MyWidget { focus: true } + MouseRegion { anchors.fill: parent; onClicked: { Page.focus = true } } +} +\endcode +\endtable + +\image declarative-qmlfocus3.png + +When a QML item explicitly relinquishes focus (by setting its +\c {Item::focus} property to false while it has \e {active focus}), the system +does not automatically select another element to receive focus. That is, it +is possible for there to be no currently \e {active focus}. + +\section1 Advanced uses of Focus Scopes + +Focus scopes allow focus to allocation to be easily partitioned. Several +QML items use it to this effect. + +\l ListView, for example, is itself a focus scope. Generally this isn't +noticable as \l ListView doesn't usually have manually added visual children. +By being a focus scope, \l ListView can focus the current list item without +worrying about how that will effect the rest of the application. This allows +the current item delegate to react to key presses. + +This contrived example shows how this works. Pressing the \c Return key will +print the name of the current list item. + +\table +\row +\o \code +Rectangle { + color: "lightsteelblue"; width: 240; height: 320 + + ListView { + id: MyView; anchors.fill: parent; focus: true + model: ListModel { + ListElement { name: "Bob" } + ListElement { name: "John" } + ListElement { name: "Michael" } + } + delegate: FocusScope { + width: contents.width; height: contents.height + Text { text: name } + KeyActions { return: "print(name)"; focus: true } + } + } +} +\endcode +\o \image declarative-qmlfocus4.png +\endtable + +While the example is simple, there's a lot going on behind the scenes. Whenever +the current item changes, the \l ListView sets the delegate's \c {Item::focus} +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 +actually performs the work of handling the \e {Return} key. + +All of the QML view classes, such as \l PathView and \l GridView, behave +in a similar mannor to allow key handling in their respective delegates. + +\section1 Focus Panels + +Traditional UIs are composed of many top-level windows. Windows actually +perform two tasks - they act as the visual bounds for a widget, and they segment +focus. Each window has a separate focused widget, that becomes (to mix +terminologies) the \e {active focus} widget when the window is the active +window. + +### Focus panels do basically the same thing. +*/ diff --git a/doc/src/declarative/measuring-performance.qdoc b/doc/src/declarative/measuring-performance.qdoc new file mode 100644 index 0000000..8c95422 --- /dev/null +++ b/doc/src/declarative/measuring-performance.qdoc @@ -0,0 +1,81 @@ +/*! +\page optimizing-performance.html +\target optimizing-performance +\title Optimizing Performance in QML + +The Qt Declarative module includes several tools to help measure performance. + +\section1 Performance Logging + +The declarative module uses the functionality provided by QPerformanceLog to log performance information. To see this information you can add the following to src.pro: + +\code +DEFINES += Q_ENABLE_PERFORMANCE_LOG +\endcode + +The performance information will be printed to screen on a QML application startup, or when running the viewer can be forced at anytime by pressing 'F3' on the keyboard. + +Additional logging can be enabled by adding the relevant categories to qfxperf.h and qfxperf.cpp. + +For example, to measure the cost of calculating the size of a text item, you would first define a TextSize category by adding the following: + +\code +//in qfxperf.h +Q_DECLARE_PERFORMANCE_METRIC(TextSize); + +//in qfxperf.cpp +Q_DEFINE_PERFORMANCE_METRIC(TextSize, "Text Size Calculation"); +\endcode + +You could then use this category in the code: + +\code +void QFxText::updateSize() +{ + QFxPerfTimer<QFxPerf::TextSize> perf; + ... +} +\endcode + +Because there is no cost for a QFxPerfTimer when Q_ENABLE_PERFORMANCE_LOG is not defined, this line can persist in the code and be used to help detect performance bottlenecks and regressions. See the QPerformanceLog documentation for more information on this performance framework. + +\section1 FPS Measurements + +When running the viewer, pressing 'F2' on the keyboard while a QML program is running will cause information on cost-per-frame and frames-per-second (FPS) to be printed to the console. + +The information printed includes: +\list +\o \e repaint(): the total time spent painting. +\o \e paint(): the time spent by Qt painting. +\o \e timeBetweenFrames: the total time spent per frame. This number minus repaint() gives a good idea of how much time is spent on things besides painting. A high number here with a low number for repaint() indicates expensive calculations happening each frame. +\endlist + +\section1 Improving Performance + +The following tips can help decrease startup time for QML-based appications. + +\section2 Images + +\list +\o Use jpg instead of png for photo-like images. On the N810, this can save 150ms for a large (320x480) image. + +\o If you are configuring Qt, configure out any image plugins you don't plan to support (mng and svg are the most expensive). On the N810, this can save 75-100ms startup time. For example: + +\code +configure -no-libmng -no-svg -no-libtiff +\endcode + +\o In some cases running pngcrush, optipng, gifsicle or other similar tools can give some improvement. + +We are also investigating support for the loading of uncompressed images. This will provide opportunites to decrease startup time at the cost of increased storage space. +\endlist + +\section2 Fonts + +\list +\o Use qpf instead of ttf. When using multiple font sizes and weights on the N810, this can save 125ms startup time compared to a ttf 'clean' run, and 40-50ms on subsequent runs (ttfs are shared by open applications). +\endlist + +*/ + +*/ diff --git a/doc/src/declarative/modules.qdoc b/doc/src/declarative/modules.qdoc new file mode 100644 index 0000000..7c67f60 --- /dev/null +++ b/doc/src/declarative/modules.qdoc @@ -0,0 +1,105 @@ +/*! +\target qmlmodules +\page qmlmodules.html +\title Modules + +A \bold module is a collection of QML types. + +To use types from a module it must be imported using the \c import statement. Successive +import statements override earlier import statements. + +\section1 Importing Built-in Types + +To use built-in types, you must import the module defining them. +For example, to use types from Qt, import it: + +\code +import Qt 4.6 +\endcode + +This makes available all types in Qt that were available in Qt 4.6, regardless of the +actual version of Qt executing the QML. + +Modules can be compiled-in (such as the Qt module), or they can be +defined in QML files. + +\section1 Importing QML Files + +To import types defined in QML files in directories relative to the file importing them, +a quoted import directory is used: + +\code +import "path" +\endcode + +This allows all components defined in the directory \c path to be used in +the component where this statement appears. + +To import types defined in QML files that are installed somewhere on the system, +an unquoted URI is used: + +\code +import com.nokia.CoolStuff 1.0 +\endcode + +This will access file in the directory \c com/nokia/CoolStuff/, found in some +location determined outside QML. See QmlEngine::addImportPath() and the \c -L option +to the \l {qmlviewer}{viewer} application. + +The directory of installed files must include a file \c qmldir which specifies the +mapping from all type names to versioned QML files. It is a list of lines of the form: + +\code +# <Comment> +<TypeName> <VersionRange> <File> +\endcode + +<TypeName> is the type being made available; <VersionRange> is either a single version +number like \c 4.0 or a range of minor versions like \c 4.0-2; <File> is the (relative) +file name of the QML file defining the type. +The same type can be provided by different files in different versions. +If a type is in multiple major versions, it should be listed on a separate line. + +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. + +Installed files \e must be referred to by version information described above, +local files \e may have it. + +The versioning system ensures that a given QML file will work regardless of the version +of installed software, since a versioned import \e only imports types for that version, +leaving other identifiers available, even if the actual installed version might otherwise +use those identifiers. + +\section1 Namespaces - Named Imports + +When importing content it by default imports types into the global namespace. +You may choose to import the module into another namespace, either to allow identically-named +types to be referenced, or purely for readability. + +To import a module into a namespace: + +\code +import Qt 4.6 as TheQtLibrary +\endcode + +Types from Qt 4.6 may then be used, but only by qualifying them with the namespace: + +\code +TheQtLibrary.Rectangle { ... } +\endcode + +Multiple modules can be imported into the same namespace in the same way that multiple +modules can be imported into the global namespace: + +\code +import Qt 4.6 as Nokia +import Ovi 1.0 as Nokia +\endcode +*/ + +/* + +See original requirement QT-558. + +*/ diff --git a/doc/src/declarative/pics/3d-axis.png b/doc/src/declarative/pics/3d-axis.png Binary files differnew file mode 100644 index 0000000..1a587ff --- /dev/null +++ b/doc/src/declarative/pics/3d-axis.png diff --git a/doc/src/declarative/pics/3d-rotation-axis.png b/doc/src/declarative/pics/3d-rotation-axis.png Binary files differnew file mode 100644 index 0000000..1b17261 --- /dev/null +++ b/doc/src/declarative/pics/3d-rotation-axis.png diff --git a/doc/src/declarative/pics/BorderImage.png b/doc/src/declarative/pics/BorderImage.png Binary files differnew file mode 100644 index 0000000..651dd8a --- /dev/null +++ b/doc/src/declarative/pics/BorderImage.png diff --git a/doc/src/declarative/pics/ListViewHighlight.png b/doc/src/declarative/pics/ListViewHighlight.png Binary files differnew file mode 100644 index 0000000..02bf51d --- /dev/null +++ b/doc/src/declarative/pics/ListViewHighlight.png diff --git a/doc/src/declarative/pics/ListViewHorizontal.png b/doc/src/declarative/pics/ListViewHorizontal.png Binary files differnew file mode 100644 index 0000000..4633a0e --- /dev/null +++ b/doc/src/declarative/pics/ListViewHorizontal.png diff --git a/doc/src/declarative/pics/ListViewSections.png b/doc/src/declarative/pics/ListViewSections.png Binary files differnew file mode 100644 index 0000000..9270126 --- /dev/null +++ b/doc/src/declarative/pics/ListViewSections.png diff --git a/doc/src/declarative/pics/ListViewVertical.png b/doc/src/declarative/pics/ListViewVertical.png Binary files differnew file mode 100644 index 0000000..e0b23d9 --- /dev/null +++ b/doc/src/declarative/pics/ListViewVertical.png diff --git a/doc/src/declarative/pics/anchors.svg b/doc/src/declarative/pics/anchors.svg new file mode 100644 index 0000000..08b00ed --- /dev/null +++ b/doc/src/declarative/pics/anchors.svg @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="744.09448819" + height="1052.3622047" + id="svg1910" + sodipodi:version="0.32" + inkscape:version="0.44.1" + inkscape:export-filename="/home/mbrasser/work/Kinetic/ngui/doc/src/pics/anchors_example2.png" + inkscape:export-xdpi="189.65207" + inkscape:export-ydpi="189.65207" + sodipodi:docbase="/home/mbrasser/work/Kinetic/ngui/doc/src/pics" + sodipodi:docname="anchors.svg"> + <defs + id="defs1912" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + gridtolerance="10000" + guidetolerance="10" + objecttolerance="10" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.979899" + inkscape:cx="431.57095" + inkscape:cy="413.38853" + inkscape:document-units="px" + inkscape:current-layer="layer1" + inkscape:window-width="1386" + inkscape:window-height="971" + inkscape:window-x="0" + inkscape:window-y="0" /> + <metadata + id="metadata1915"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <rect + style="opacity:1;fill:none;fill-opacity:1;stroke:black;stroke-width:0.52033526;stroke-miterlimit:4;stroke-dasharray:1.04067054, 0.52033527;stroke-dashoffset:0;stroke-opacity:1" + id="rect2807" + width="36.245155" + height="32.204544" + x="390.23157" + y="574.62024" /> + <rect + style="opacity:1;fill:none;fill-opacity:1;stroke:black;stroke-width:0.44547796;stroke-miterlimit:4;stroke-dasharray:0.89095592, 0.44547796;stroke-dashoffset:0;stroke-opacity:1" + id="rect2809" + width="59.048447" + height="14.601732" + x="430.82993" + y="574.9483" /> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="399.40982" + y="594.76312" + id="text3696"><tspan + sodipodi:role="line" + id="tspan3698" + x="399.40982" + y="594.76312">pic</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="445.84048" + y="586.5423" + id="text3700"><tspan + sodipodi:role="line" + id="tspan3702" + x="445.84048" + y="586.5423">label</tspan></text> + </g> +</svg> diff --git a/doc/src/declarative/pics/animatedimageitem.gif b/doc/src/declarative/pics/animatedimageitem.gif Binary files differnew file mode 100644 index 0000000..85c3cb5 --- /dev/null +++ b/doc/src/declarative/pics/animatedimageitem.gif diff --git a/doc/src/declarative/pics/axisrotation.png b/doc/src/declarative/pics/axisrotation.png Binary files differnew file mode 100644 index 0000000..409a9e9 --- /dev/null +++ b/doc/src/declarative/pics/axisrotation.png diff --git a/doc/src/declarative/pics/blur_example.png b/doc/src/declarative/pics/blur_example.png Binary files differnew file mode 100644 index 0000000..763b112 --- /dev/null +++ b/doc/src/declarative/pics/blur_example.png diff --git a/doc/src/declarative/pics/content.png b/doc/src/declarative/pics/content.png Binary files differnew file mode 100644 index 0000000..47a98ac --- /dev/null +++ b/doc/src/declarative/pics/content.png diff --git a/doc/src/declarative/pics/declarative-qmlfocus1.png b/doc/src/declarative/pics/declarative-qmlfocus1.png Binary files differnew file mode 100644 index 0000000..fd05146 --- /dev/null +++ b/doc/src/declarative/pics/declarative-qmlfocus1.png diff --git a/doc/src/declarative/pics/declarative-qmlfocus2.png b/doc/src/declarative/pics/declarative-qmlfocus2.png Binary files differnew file mode 100644 index 0000000..a946e2c --- /dev/null +++ b/doc/src/declarative/pics/declarative-qmlfocus2.png diff --git a/doc/src/declarative/pics/declarative-qmlfocus3.png b/doc/src/declarative/pics/declarative-qmlfocus3.png Binary files differnew file mode 100644 index 0000000..ba55f76 --- /dev/null +++ b/doc/src/declarative/pics/declarative-qmlfocus3.png diff --git a/doc/src/declarative/pics/declarative-qmlfocus4.png b/doc/src/declarative/pics/declarative-qmlfocus4.png Binary files differnew file mode 100644 index 0000000..e21f2a6 --- /dev/null +++ b/doc/src/declarative/pics/declarative-qmlfocus4.png diff --git a/doc/src/declarative/pics/edge1.png b/doc/src/declarative/pics/edge1.png Binary files differnew file mode 100644 index 0000000..f4bc16d --- /dev/null +++ b/doc/src/declarative/pics/edge1.png diff --git a/doc/src/declarative/pics/edge2.png b/doc/src/declarative/pics/edge2.png Binary files differnew file mode 100644 index 0000000..71bda8e --- /dev/null +++ b/doc/src/declarative/pics/edge2.png diff --git a/doc/src/declarative/pics/edge3.png b/doc/src/declarative/pics/edge3.png Binary files differnew file mode 100644 index 0000000..51bb894 --- /dev/null +++ b/doc/src/declarative/pics/edge3.png diff --git a/doc/src/declarative/pics/edge4.png b/doc/src/declarative/pics/edge4.png Binary files differnew file mode 100644 index 0000000..aee3bd1 --- /dev/null +++ b/doc/src/declarative/pics/edge4.png diff --git a/doc/src/declarative/pics/edges.png b/doc/src/declarative/pics/edges.png Binary files differnew file mode 100644 index 0000000..211b101 --- /dev/null +++ b/doc/src/declarative/pics/edges.png diff --git a/doc/src/declarative/pics/edges.svg b/doc/src/declarative/pics/edges.svg new file mode 100644 index 0000000..25698ca --- /dev/null +++ b/doc/src/declarative/pics/edges.svg @@ -0,0 +1,185 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="744.09448819" + height="1052.3622047" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.44.1" + sodipodi:docbase="/home/mbrasser" + sodipodi:docname="edges.svg"> + <defs + id="defs4"> + <marker + inkscape:stockid="Arrow1Mstart" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow1Mstart" + style="overflow:visible"> + <path + id="path3850" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" + transform="scale(0.4) translate(10,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Lstart" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow1Lstart" + style="overflow:visible"> + <path + id="path3856" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" + transform="scale(0.8) translate(12.5,0)" /> + </marker> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + gridtolerance="10000" + guidetolerance="10" + objecttolerance="10" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="2.8583315" + inkscape:cx="372.04724" + inkscape:cy="596.15198" + inkscape:document-units="px" + inkscape:current-layer="layer1" + inkscape:window-width="1279" + inkscape:window-height="969" + inkscape:window-x="0" + inkscape:window-y="0" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <rect + style="opacity:1;fill:#0ca9fa;fill-opacity:1;stroke:black;stroke-width:0.04639034;stroke-miterlimit:4;stroke-dasharray:0.09278069, 0.04639034;stroke-dashoffset:0;stroke-opacity:1" + id="rect1872" + width="33.656742" + height="39.808346" + x="208.86543" + y="390.22763" + rx="5" + ry="5" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1, 1;stroke-dashoffset:0;stroke-opacity:1" + d="M 225.51888,380.99149 C 225.51888,439.06733 225.86873,439.06733 225.86873,439.06733" + id="path2760" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1, 1;stroke-dashoffset:0;stroke-opacity:1" + d="M 242.97392,380.99149 C 242.97392,439.06733 243.32377,439.06733 243.32377,439.06733" + id="path3647" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1, 1;stroke-dashoffset:0;stroke-opacity:1" + d="M 208.33832,380.99149 C 208.33832,439.06733 208.68817,439.06733 208.68817,439.06733" + id="path3649" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1, 1;stroke-dashoffset:0;stroke-opacity:1" + d="M 195.91848,409.67956 C 256.44329,409.67956 256.09344,409.67956 256.09344,409.67956" + id="path3651" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1, 1;stroke-dashoffset:0;stroke-opacity:1" + d="M 195.91848,429.97112 C 256.44329,429.97112 256.09344,429.97112 256.09344,429.97112" + id="path3653" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1, 1;stroke-dashoffset:0;stroke-opacity:1" + d="M 195.91848,390.78742 C 256.44329,390.78742 256.09344,390.78742 256.09344,390.78742" + id="path3655" /> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="258.54242" + y="393.58627" + id="text3657"><tspan + sodipodi:role="line" + id="tspan3659" + x="258.54242" + y="393.58627" + style="font-size:10px">Top</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="258.78955" + y="412.28455" + id="text3661"><tspan + sodipodi:role="line" + id="tspan3663" + x="258.78955" + y="412.28455" + style="font-size:10px">VerticalCenter</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="260.18896" + y="433.27582" + id="text3665"><tspan + sodipodi:role="line" + id="tspan3667" + x="260.18896" + y="433.27582" + style="font-size:10px">Bottom</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="198.96443" + y="376.24954" + id="text3669"><tspan + sodipodi:role="line" + id="tspan3671" + x="198.96443" + y="376.24954" + style="font-size:10px">Left</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="230.55408" + y="375.39383" + id="text3673"><tspan + sodipodi:role="line" + id="tspan3675" + x="230.55408" + y="375.39383" + style="font-size:10px">Right</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="186.71951" + y="355.25827" + id="text3677"><tspan + sodipodi:role="line" + id="tspan3679" + x="186.71951" + y="355.25827" + style="font-size:10px">HorizontalCenter</tspan></text> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart)" + d="M 224.2567,375.39382 C 227.40539,356.85154 227.75525,357.20139 227.75525,357.20139" + id="path3681" /> + </g> +</svg> diff --git a/doc/src/declarative/pics/edges_examples.svg b/doc/src/declarative/pics/edges_examples.svg new file mode 100644 index 0000000..31e9901 --- /dev/null +++ b/doc/src/declarative/pics/edges_examples.svg @@ -0,0 +1,109 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="744.09448819" + height="1052.3622047" + id="svg3885" + sodipodi:version="0.32" + inkscape:version="0.44.1" + inkscape:export-filename="/home/mbrasser/edge4.png" + inkscape:export-xdpi="189.65207" + inkscape:export-ydpi="189.65207" + sodipodi:docbase="/home/mbrasser/work/Kinetic/ngui/doc/src/pics" + sodipodi:docname="edges_examples.svg"> + <defs + id="defs3887" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + gridtolerance="10000" + guidetolerance="10" + objecttolerance="10" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="2" + inkscape:cx="162.62912" + inkscape:cy="591.92069" + inkscape:document-units="px" + inkscape:current-layer="layer1" + inkscape:window-width="928" + inkscape:window-height="624" + inkscape:window-x="0" + inkscape:window-y="495" /> + <metadata + id="metadata3890"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <rect + style="opacity:1;fill:#0ca9fa;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3893" + width="50" + height="50" + x="100" + y="414.36218" /> + <rect + style="opacity:1;fill:#fa0c2a;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3895" + width="104" + height="50" + x="150" + y="414.36218" /> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="109" + y="443.65125" + id="text3897"><tspan + sodipodi:role="line" + id="tspan3899" + x="109" + y="443.65125">rect1</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="186.54297" + y="443.65125" + id="text3901"><tspan + sodipodi:role="line" + id="tspan3903" + x="186.54297" + y="443.65125">rect2</tspan></text> + <rect + style="opacity:1;fill:#0ca9fa;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect3905" + width="50" + height="50" + x="254" + y="414.36218" /> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="263" + y="443.65125" + id="text3907"><tspan + sodipodi:role="line" + id="tspan3909" + x="263" + y="443.65125">rect3</tspan></text> + </g> +</svg> diff --git a/doc/src/declarative/pics/edges_qml.png b/doc/src/declarative/pics/edges_qml.png Binary files differnew file mode 100644 index 0000000..73f22f9 --- /dev/null +++ b/doc/src/declarative/pics/edges_qml.png diff --git a/doc/src/declarative/pics/edges_qml.svg b/doc/src/declarative/pics/edges_qml.svg new file mode 100644 index 0000000..1814ec6 --- /dev/null +++ b/doc/src/declarative/pics/edges_qml.svg @@ -0,0 +1,188 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="744.09448819" + height="1052.3622047" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.44.1" + sodipodi:docbase="/home/mbrasser/work/Kinetic/ngui/doc/src/pics" + sodipodi:docname="edges_qml.svg" + inkscape:export-filename="/home/mbrasser/edges_qml.png" + inkscape:export-xdpi="284.45999" + inkscape:export-ydpi="284.45999"> + <defs + id="defs4"> + <marker + inkscape:stockid="Arrow1Mstart" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow1Mstart" + style="overflow:visible"> + <path + id="path3850" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" + transform="scale(0.4) translate(10,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Lstart" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow1Lstart" + style="overflow:visible"> + <path + id="path3856" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" + transform="scale(0.8) translate(12.5,0)" /> + </marker> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + gridtolerance="10000" + guidetolerance="10" + objecttolerance="10" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="2.8583315" + inkscape:cx="372.04724" + inkscape:cy="596.15198" + inkscape:document-units="px" + inkscape:current-layer="layer1" + inkscape:window-width="1279" + inkscape:window-height="969" + inkscape:window-x="0" + inkscape:window-y="0" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <rect + style="opacity:1;fill:#0ca9fa;fill-opacity:1;stroke:black;stroke-width:0.04639034;stroke-miterlimit:4;stroke-dasharray:0.09278069, 0.04639034;stroke-dashoffset:0;stroke-opacity:1" + id="rect1872" + width="33.656742" + height="39.808346" + x="208.86543" + y="390.22763" + rx="5" + ry="5" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1, 1;stroke-dashoffset:0;stroke-opacity:1" + d="M 225.51888,380.99149 C 225.51888,439.06733 225.86873,439.06733 225.86873,439.06733" + id="path2760" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1, 1;stroke-dashoffset:0;stroke-opacity:1" + d="M 242.97392,380.99149 C 242.97392,439.06733 243.32377,439.06733 243.32377,439.06733" + id="path3647" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1, 1;stroke-dashoffset:0;stroke-opacity:1" + d="M 208.33832,380.99149 C 208.33832,439.06733 208.68817,439.06733 208.68817,439.06733" + id="path3649" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1, 1;stroke-dashoffset:0;stroke-opacity:1" + d="M 195.91848,409.67956 C 256.44329,409.67956 256.09344,409.67956 256.09344,409.67956" + id="path3651" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1, 1;stroke-dashoffset:0;stroke-opacity:1" + d="M 195.91848,429.97112 C 256.44329,429.97112 256.09344,429.97112 256.09344,429.97112" + id="path3653" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1, 1;stroke-dashoffset:0;stroke-opacity:1" + d="M 195.91848,390.78742 C 256.44329,390.78742 256.09344,390.78742 256.09344,390.78742" + id="path3655" /> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="258.54242" + y="393.58627" + id="text3657"><tspan + sodipodi:role="line" + id="tspan3659" + x="258.54242" + y="393.58627" + style="font-size:10px">top</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="258.78955" + y="412.28455" + id="text3661"><tspan + sodipodi:role="line" + id="tspan3663" + x="258.78955" + y="412.28455" + style="font-size:10px">verticalCenter</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="260.18896" + y="433.27582" + id="text3665"><tspan + sodipodi:role="line" + id="tspan3667" + x="260.18896" + y="433.27582" + style="font-size:10px">bottom</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="200.96443" + y="376.24954" + id="text3669"><tspan + sodipodi:role="line" + id="tspan3671" + x="200.96443" + y="376.24954" + style="font-size:10px">left</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="232.55408" + y="375.39383" + id="text3673"><tspan + sodipodi:role="line" + id="tspan3675" + x="232.55408" + y="375.39383" + style="font-size:10px">right</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="190.71951" + y="355.25827" + id="text3677"><tspan + sodipodi:role="line" + id="tspan3679" + x="190.71951" + y="355.25827" + style="font-size:10px">horizontalCenter</tspan></text> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Mstart);stroke-opacity:1" + d="M 226.2567,375.39382 C 229.40539,356.85154 229.75525,357.20139 229.75525,357.20139" + id="path3681" /> + </g> +</svg> diff --git a/doc/src/declarative/pics/flickable.gif b/doc/src/declarative/pics/flickable.gif Binary files differnew file mode 100644 index 0000000..f7a3319 --- /dev/null +++ b/doc/src/declarative/pics/flickable.gif diff --git a/doc/src/declarative/pics/flipable.gif b/doc/src/declarative/pics/flipable.gif Binary files differnew file mode 100644 index 0000000..6386f06 --- /dev/null +++ b/doc/src/declarative/pics/flipable.gif diff --git a/doc/src/declarative/pics/gradient.png b/doc/src/declarative/pics/gradient.png Binary files differnew file mode 100644 index 0000000..5eefdd2 --- /dev/null +++ b/doc/src/declarative/pics/gradient.png diff --git a/doc/src/declarative/pics/gridLayout_example.png b/doc/src/declarative/pics/gridLayout_example.png Binary files differnew file mode 100644 index 0000000..6b120e9 --- /dev/null +++ b/doc/src/declarative/pics/gridLayout_example.png diff --git a/doc/src/declarative/pics/gridview.png b/doc/src/declarative/pics/gridview.png Binary files differnew file mode 100644 index 0000000..3726893 --- /dev/null +++ b/doc/src/declarative/pics/gridview.png diff --git a/doc/src/declarative/pics/highlight.gif b/doc/src/declarative/pics/highlight.gif Binary files differnew file mode 100644 index 0000000..fbef256 --- /dev/null +++ b/doc/src/declarative/pics/highlight.gif diff --git a/doc/src/declarative/pics/horizontalpositioner_example.png b/doc/src/declarative/pics/horizontalpositioner_example.png Binary files differnew file mode 100644 index 0000000..42f90ec --- /dev/null +++ b/doc/src/declarative/pics/horizontalpositioner_example.png diff --git a/doc/src/declarative/pics/margins_qml.png b/doc/src/declarative/pics/margins_qml.png Binary files differnew file mode 100644 index 0000000..d7d73a3 --- /dev/null +++ b/doc/src/declarative/pics/margins_qml.png diff --git a/doc/src/declarative/pics/margins_qml.svg b/doc/src/declarative/pics/margins_qml.svg new file mode 100644 index 0000000..1f0ff02 --- /dev/null +++ b/doc/src/declarative/pics/margins_qml.svg @@ -0,0 +1,196 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="744.09448819" + height="1052.3622047" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.44.1" + sodipodi:docbase="/home/mbrasser/work/Kinetic/ngui/doc/src/pics" + sodipodi:docname="margins_qml.svg" + inkscape:export-filename="/home/mbrasser/edges_qml.png" + inkscape:export-xdpi="284.45999" + inkscape:export-ydpi="284.45999"> + <defs + id="defs4"> + <marker + inkscape:stockid="Arrow1Send" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow1Send" + style="overflow:visible;"> + <path + id="path2976" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;" + transform="scale(0.2) rotate(180) translate(6,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Sstart" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow1Sstart" + style="overflow:visible"> + <path + id="path2979" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" + transform="scale(0.2) translate(6,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mstart" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow1Mstart" + style="overflow:visible"> + <path + id="path3850" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" + transform="scale(0.4) translate(10,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Lstart" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow1Lstart" + style="overflow:visible"> + <path + id="path3856" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" + transform="scale(0.8) translate(12.5,0)" /> + </marker> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + gridtolerance="10000" + guidetolerance="10" + objecttolerance="10" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="2.8583315" + inkscape:cx="372.04724" + inkscape:cy="596.15198" + inkscape:document-units="px" + inkscape:current-layer="layer1" + inkscape:window-width="1279" + inkscape:window-height="969" + inkscape:window-x="0" + inkscape:window-y="0" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <rect + style="opacity:1;fill:#0ca9fa;fill-opacity:1;stroke:black;stroke-width:0.04639034;stroke-miterlimit:4;stroke-dasharray:0.09278069, 0.04639034;stroke-dashoffset:0;stroke-opacity:1" + id="rect1872" + width="33.656742" + height="39.808346" + x="208.86543" + y="390.22763" + rx="5" + ry="5" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.02602077;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.02602088, 1.02602088;stroke-dashoffset:0;stroke-opacity:1" + d="M 252.98692,377.00435 C 252.98692,443.05433 253.31077,443.05433 253.31077,443.05433" + id="path3647" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.02601969;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.02602007, 1.02602007;stroke-dashoffset:0;stroke-opacity:1" + d="M 198.35134,377.00433 C 198.35134,443.05431 198.67515,443.05431 198.67515,443.05431" + id="path3649" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.02421367;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.02421381, 1.02421381;stroke-dashoffset:0;stroke-opacity:1" + d="M 193.94282,437.97112 C 257.43421,437.97112 257.06721,437.97112 257.06721,437.97112" + id="path3653" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1.02421367;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.02421381, 1.02421381;stroke-dashoffset:0;stroke-opacity:1" + d="M 193.94282,380.78742 C 257.43421,380.78742 257.06721,380.78742 257.06721,380.78742" + id="path3655" /> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="260.29169" + y="388.78741" + id="text1911"><tspan + sodipodi:role="line" + id="tspan1913" + x="260.29169" + y="388.78741" + style="font-size:10px">topMargin</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="259.65204" + y="437.27798" + id="text1915"><tspan + sodipodi:role="line" + id="tspan1917" + x="259.65204" + y="437.27798" + style="font-size:10px">bottomMargin</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="170.07939" + y="454.4209" + id="text1919"><tspan + sodipodi:role="line" + id="tspan1921" + x="170.07939" + y="454.4209" + style="font-size:10px">leftMargin</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="228.47504" + y="454.4209" + id="text1923"><tspan + sodipodi:role="line" + id="tspan1925" + x="228.47504" + y="454.4209" + style="font-size:10px">rightMargin</tspan></text> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:0.92020172px;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Sstart);marker-end:url(#Arrow1Send);stroke-opacity:1" + d="M 225.6938,382.51213 C 225.6938,388.91693 225.6938,388.91693 225.6938,388.91693" + id="path1929" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:0.92007709px;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Sstart);marker-end:url(#Arrow1Send);stroke-opacity:1" + d="M 225.6938,430.56703 C 225.6938,436.97192 225.6938,436.97192 225.6938,436.97192" + id="path3000" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Sstart);marker-mid:none;marker-end:url(#Arrow1Send);stroke-opacity:1" + d="M 201.16631,410.1318 C 207.81355,410.1318 207.81355,410.1318 207.81355,410.1318" + id="path3002" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Arrow1Sstart);marker-mid:none;marker-end:url(#Arrow1Send);stroke-opacity:1" + d="M 244.02348,410.1318 C 250.67072,410.1318 250.67072,410.1318 250.67072,410.1318" + id="path3889" /> + </g> +</svg> diff --git a/doc/src/declarative/pics/particles.gif b/doc/src/declarative/pics/particles.gif Binary files differnew file mode 100644 index 0000000..763a8a8 --- /dev/null +++ b/doc/src/declarative/pics/particles.gif diff --git a/doc/src/declarative/pics/pathview.gif b/doc/src/declarative/pics/pathview.gif Binary files differnew file mode 100644 index 0000000..4052eb2 --- /dev/null +++ b/doc/src/declarative/pics/pathview.gif diff --git a/doc/src/declarative/pics/positioner-add.gif b/doc/src/declarative/pics/positioner-add.gif Binary files differnew file mode 100644 index 0000000..86e9247 --- /dev/null +++ b/doc/src/declarative/pics/positioner-add.gif diff --git a/doc/src/declarative/pics/positioner-move.gif b/doc/src/declarative/pics/positioner-move.gif Binary files differnew file mode 100644 index 0000000..1825c22 --- /dev/null +++ b/doc/src/declarative/pics/positioner-move.gif diff --git a/doc/src/declarative/pics/positioner-remove.gif b/doc/src/declarative/pics/positioner-remove.gif Binary files differnew file mode 100644 index 0000000..7086511 --- /dev/null +++ b/doc/src/declarative/pics/positioner-remove.gif diff --git a/doc/src/declarative/pics/propanim.gif b/doc/src/declarative/pics/propanim.gif Binary files differnew file mode 100644 index 0000000..f86406e --- /dev/null +++ b/doc/src/declarative/pics/propanim.gif diff --git a/doc/src/declarative/pics/qtlogo.png b/doc/src/declarative/pics/qtlogo.png Binary files differnew file mode 100644 index 0000000..399bd0b --- /dev/null +++ b/doc/src/declarative/pics/qtlogo.png diff --git a/doc/src/declarative/pics/reflection_example.png b/doc/src/declarative/pics/reflection_example.png Binary files differnew file mode 100644 index 0000000..fd9bb48 --- /dev/null +++ b/doc/src/declarative/pics/reflection_example.png diff --git a/doc/src/declarative/pics/repeater.png b/doc/src/declarative/pics/repeater.png Binary files differnew file mode 100644 index 0000000..973df27 --- /dev/null +++ b/doc/src/declarative/pics/repeater.png diff --git a/doc/src/declarative/pics/scalegrid.svg b/doc/src/declarative/pics/scalegrid.svg new file mode 100644 index 0000000..e386f3d --- /dev/null +++ b/doc/src/declarative/pics/scalegrid.svg @@ -0,0 +1,183 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="744.09448819" + height="1052.3622047" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.44.1" + sodipodi:docbase="/home/mbrasser/work/Kinetic/ngui/doc/src/pics" + sodipodi:docname="scalegrid.svg" + inkscape:export-filename="/home/mbrasser/work/Kinetic/ngui/doc/src/pics/scalegrid.png" + inkscape:export-xdpi="189.65207" + inkscape:export-ydpi="189.65207"> + <defs + id="defs4" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + gridtolerance="50" + guidetolerance="10" + objecttolerance="10" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="3.2163554" + inkscape:cx="173.89302" + inkscape:cy="703.69531" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="true" + inkscape:grid-bbox="false" + inkscape:guide-bbox="false" + inkscape:window-width="1409" + inkscape:window-height="1016" + inkscape:window-x="0" + inkscape:window-y="0" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <rect + style="opacity:1;fill:red;fill-opacity:1;stroke:none;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect1876" + width="45.104" + height="45.137001" + x="119.16868" + y="301.00308" + rx="5" + ry="5" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:0.3965202;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.79304035, 0.39652018;stroke-dashoffset:0;stroke-opacity:1" + d="M 157.02483,295.52571 C 157.02483,352.04784 157.02483,352.04784 157.02483,352.04784" + id="path2766" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:0.39652267;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.79304534, 0.39652268;stroke-dashoffset:0;stroke-opacity:1" + d="M 126.2,295.64284 C 126.2,352.16567 126.2,352.16567 126.2,352.16567" + id="path2768" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:0.39652267;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.79304534, 0.39652268;stroke-dashoffset:0;stroke-opacity:1" + d="M 169.05321,308.25967 C 112.53038,308.25967 112.53038,308.25967 112.53038,308.25967" + id="path2770" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:0.39652267;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.79304534, 0.39652268;stroke-dashoffset:0;stroke-opacity:1" + d="M 169.08024,339.77238 C 112.55741,339.77238 112.55741,339.77238 112.55741,339.77238" + id="path2772" /> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Arial Black" + x="115.2857" + y="303.60583" + id="text2774"><tspan + sodipodi:role="line" + id="tspan2776" + x="115.2857" + y="303.60583">1</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="137.19142" + y="303.60583" + id="text2782"><tspan + sodipodi:role="line" + id="tspan2784" + x="137.19142" + y="303.60583" + style="font-family:Arial Black">2</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Arial Black" + x="161.56842" + y="303.45935" + id="text2786"><tspan + sodipodi:role="line" + id="tspan2788" + x="161.56842" + y="303.45935">3</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="114.72613" + y="327.00702" + id="text2790"><tspan + sodipodi:role="line" + id="tspan2792" + x="114.72613" + y="327.00702" + style="font-family:Arial Black">4</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="137.12404" + y="326.86053" + id="text2794"><tspan + sodipodi:role="line" + id="tspan2796" + x="137.12404" + y="326.86053" + style="font-family:Arial Black">5</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="161.49518" + y="326.86053" + id="text2798"><tspan + sodipodi:role="line" + id="tspan2800" + x="161.49518" + y="326.86053" + style="font-family:Arial Black">6</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="114.70855" + y="351.25809" + id="text2802"><tspan + sodipodi:role="line" + id="tspan2804" + x="114.70855" + y="351.25809" + style="font-family:Arial Black">7</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="137.08595" + y="351.1116" + id="text2806"><tspan + sodipodi:role="line" + id="tspan2808" + x="137.08595" + y="351.1116" + style="font-family:Arial Black">8</tspan></text> + <text + xml:space="preserve" + style="font-size:12px;font-style:normal;font-weight:normal;fill:black;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" + x="161.58307" + y="351.1116" + id="text2810"><tspan + sodipodi:role="line" + id="tspan2812" + x="161.58307" + y="351.1116" + style="font-family:Arial Black">9</tspan></text> + </g> +</svg> diff --git a/doc/src/declarative/pics/shadow_example.png b/doc/src/declarative/pics/shadow_example.png Binary files differnew file mode 100644 index 0000000..6214620 --- /dev/null +++ b/doc/src/declarative/pics/shadow_example.png diff --git a/doc/src/declarative/pics/spacing_a.png b/doc/src/declarative/pics/spacing_a.png Binary files differnew file mode 100644 index 0000000..c0fe895 --- /dev/null +++ b/doc/src/declarative/pics/spacing_a.png diff --git a/doc/src/declarative/pics/spacing_b.png b/doc/src/declarative/pics/spacing_b.png Binary files differnew file mode 100644 index 0000000..24cf640 --- /dev/null +++ b/doc/src/declarative/pics/spacing_b.png diff --git a/doc/src/declarative/pics/squish-transform.png b/doc/src/declarative/pics/squish-transform.png Binary files differnew file mode 100644 index 0000000..0eb848e --- /dev/null +++ b/doc/src/declarative/pics/squish-transform.png diff --git a/doc/src/declarative/pics/squish.png b/doc/src/declarative/pics/squish.png Binary files differnew file mode 100644 index 0000000..73bf292 --- /dev/null +++ b/doc/src/declarative/pics/squish.png diff --git a/doc/src/declarative/pics/trivialListView.png b/doc/src/declarative/pics/trivialListView.png Binary files differnew file mode 100644 index 0000000..3782570 --- /dev/null +++ b/doc/src/declarative/pics/trivialListView.png diff --git a/doc/src/declarative/pics/verticalpositioner_example.png b/doc/src/declarative/pics/verticalpositioner_example.png Binary files differnew file mode 100644 index 0000000..458dc7f --- /dev/null +++ b/doc/src/declarative/pics/verticalpositioner_example.png diff --git a/doc/src/declarative/pics/verticalpositioner_transition.gif b/doc/src/declarative/pics/verticalpositioner_transition.gif Binary files differnew file mode 100644 index 0000000..ed61adb --- /dev/null +++ b/doc/src/declarative/pics/verticalpositioner_transition.gif diff --git a/doc/src/declarative/pics/webview.png b/doc/src/declarative/pics/webview.png Binary files differnew file mode 100644 index 0000000..0d24586 --- /dev/null +++ b/doc/src/declarative/pics/webview.png diff --git a/doc/src/declarative/qmlforcpp.qdoc b/doc/src/declarative/qmlforcpp.qdoc new file mode 100644 index 0000000..5838df7 --- /dev/null +++ b/doc/src/declarative/qmlforcpp.qdoc @@ -0,0 +1,670 @@ +/*! + \page qmlforcpp.html + \target qmlforcpp + \title QML for C++ Programmers + + This page describes the QML format and how to use and extend it from C++. + + The QML syntax declaratively describes how to construct an in memory + object tree. QML is usually used to describe a visual scene graph + but it is not conceptually limited to this: the QML format is an abstract + description of \bold any object tree. + + QML also includes property bindings. Bindings are ECMAScript expressions + of a properties value. Whenever the value of the expression changes - + either for the first time at startup or subsequently thereafter - the + property is automatically updated with the new value. + + \section1 Loading and using QML Files + + QmlComponent is used to load a QML file and to create object instances. + + In QML a component is the unit of instantiation, and the most basic unit + of scope. A component is like a template for how to construct an object + tree. One component can create multiple instances of this tree, but the + template remains constant. + + The following code uses the C++ interface to create 100 red rectangles + based on a simple declarative component description. + + \code + QmlEngine engine; + QmlComponent redRectangle(&engine, "Rectangle { color: \"red\"; width: 100; height: 100 }"); + for (int ii = 0; ii < 100; ++ii) { + QObject *rectangle = redRectangle.create(); + // ... do something with the rectangle ... + } + \endcode + + Each independent file describes a QML component, but it is also possible to + create sub-components within a QML file as will be shown later. + + \section1 QML Format 101 + + This is some sample QML code. + + \code + Image { + id: myRect + x: 10 + y: 10 + width: 100 + height: 100 + source: "background.png" + + Text { + height: 50 + width: 100 + color: "white" + font.fontSize: 16 + text: "Hello world!" + } + } + \endcode + + The QML snippet shown above instantiates one \c Image instance and one + \c Text instance and sets properties on both. \bold Everything in QML + ultimately comes down to either instantiating an object instance, or + assigning a property a value. QML relies heavily on Qt's meta object system + and can only instantiate classes that derive from QObject. + + In the above example, each property is placed on its own line. You can + also place multiple properties on one line by separating them with a + semi-colon. The code below is equivalent to the example above. + + \code + Image { + id: myRect + x: 10; y: 10; width: 100; height: 100 + source: "background.png" + Text { height: 50; width: 100; color: "white"; font.fontSize: 16; text: "Hello world!" } + } + \endcode + + QML can set properties that are more complex than just simple types like + integers and strings. Properties can be object pointers or Qt interface + pointers or even lists of object or Qt interface pointers! QML is typesafe, + and will ensure that only the valid types are assigned to properties. + + Assigning an object to a property is as simple as assigning a basic + integer. Attempting to assign an object to a property when type coercian + fails will produce an error. The following shows an example of valid and of + invalid QML and the corresponding C++ classes. + + \table + \row \o + \code + class Image : public QObject + { + ... + Q_PROPERTY(ImageFilter *filter READ filter WRITE setFilter) + }; + + class ImageFilter : public QObject + { + ... + }; + \endcode + \o \code + // OK + Image { + filter: ImageFilter {} + } + + // NOT OK: Image cannot be cast into ImageFilter + Image { + filter: Image {} + } + \endcode + \endtable + + Classes can also define an optional default property. The default property + is used for assignment if no explicit property has been specified. + Any object property can be the default, even complex properties like lists + of objects. The default property of the \c Rect class is the \c children + property, a list of \c Item's. In the following example, as both \c Image + and \c Text inherit from \c Item the \c Image and \c Text instances are + added to the parent's \c children property. + + \code + Rectangle { + Image {} + Text {} + } + \endcode + + Properties that return read-only object pointers can be used recursively. + This can be used, for example, to group properties together. The + \c Text element has a \c font property that returns an object with a number + of sub-properties such as \c family, \c bold, \c italic and \c size. + QML makes it easy to interact with these grouped properties, as the + following shows - everything you would expect to work, just does. + + \table + \row \o + \code + class Text : public ... + { + ... + Q_PROPERTY(Font *font READ font); + }; + class Font : public QObject + { + ... + Q_PROPERTY(QString family READ family WRITE setFamily); + Q_PROPERTY(bool bold READ bold WRITE setBold); + Q_PROPERTY(bool italic READ italic WRITE setItalic); + Q_PROPERTY(int size READ size WRITE setSize); + }; + \endcode + \o + \code + Text { + font.family: "helvetica" + font.pointSize: 12 + font { + bold: true + italic: true + } + } + \endcode + \endtable + + \section1 Defining QML Types + + The QML engine has no intrinsic knowledge of any class types. Instead + the programmer must define the C++ types, their corresponding QML + name, library namespace, and version availability. + + \code + #define QML_DECLARE_TYPE(T) + #define QML_DEFINE_TYPE(URI,VMAJ,VFROM,VTO,QmlName,T) + \endcode + + Adding these macros to your library or executable automatically makes the + C++ type \a T available from the declarative markup language under the + name \a QmlName. Of course there's nothing stopping you using the same + name for both the C++ and the QML name! + Any type can be added to the QML engine using these macros. The only + requirements are that \a T inherits QObject, is not abstract, + and that it has a default constructor. + + \section1 Property Binding + + Assigning constant values and trees to properties will only get you so + far. Property binding allows a property's value to be dependant on the + value of other properties and data. Whenever these dependencies change, + the property's value is automatically updated. + + Property bindings are ECMAScript expressions and can be applied to any + object property. C++ classes don't have to do anything special to get + binding support other than define appropriate properties. When a non-literal + property assignment appears in a QML file, it is automatically treated as a + property binding. + + Here's a simple example that stacks a red, blue and green rectangle. + Bindings are used to ensure that the height of each is kept equal to it's + parent's. Were the root rectangle's height property to change, the child + rectangles height would be updated automatically. + + \code + Rectangle { + color: "red" + width: 100 + Rectangle { + color: "blue" + width: 50 + height: parent.height + Rectangle { + color: "green" + width: 25 + height: parent.height + } + } + } + \endcode + + Binding expressions execute in a context. A context behaves as a scope and + defines how the expression resolves property and variable names. Although + the two expressions in the last example are the same, the value of \c parent + resolves differently because each executes in a different context. Although + QML generally takes care of everything for the programmer, a thorough + understanding of bind contexts is important in some of the more complex QML + structures. + + Every expression is executed in a bind context, encapsulated by the + QmlContext C++ class. As covered in the class documentation, a + bind context contains a map of names to values, and a list of default + objects. When resolving a name, the name to value map is searched first. + If the name cannot be found, the default object's are iterated in turn and + the context attempts to resolve the name as a property of one of the default + objects. + + There are generally two contexts involved in the execution of a binding. + The first is the "object context" - a bind context associated with the + closest instantiated object and containing just one default object, and + that's instantiated object itself. The effect of the object + context is pretty simple - names in the binding expression resolve to + properties on the object first. It is important to note - particularly in + the case of grouped properties - the object context is that of the + instantiated object, the consequences of which are shown below. + + \code + // OK // NOT OK + Text { Text { + font { font { + bold: font.italic bold: italic + } } + } } + \endcode + + The second context is the "component context". Each QML component (and + consequently each QML file) is created in its own unique binding context. + Like the object context, the component context contains just one default + object - but in this case it is the component's root object. An example + will illustrate best - the resultant text will read "background.png". + + \code + Image { + source: "background.png" + Text { + text: source + } + } + \endcode + + If the name is not found in either of these contexts, the context heirarchy + is searched parent-by-parent until the name is either found, or the + heirarchy is exhausted. + + The first property binding example shown involved fixing the height of three + rectangles. It did this by fixing the height of each rectangle to its + parent, rather than fixing them all to a single common point. Here's the + example rewritten to do just that. + + \code + Rectangle { + color: "red" + width: 100 + Rectangle { + color: "blue" + width: 50 + height: parent.height + Rectangle { + color: "green" + width: 25 + height: parent.parent.height + } + } + } + \endcode + + Clearly this sort of fragile relationship is undesirable and unmanageable - + moving the green rectangle to be a sibling of the blue or introducing a + further rectangle between the two would break the example. + + To address this problem, QML includes a way to directly reference any object + within a component (or parent component for that matter), called "ids". + Developers assign an object an id, and can then reference it directly by + name. Developers assign an object an id by setting the special \c id + property. Every object automatically has this magical property (if the + object also has an actual property called \c id, that gets set too). As + an id allows an object to be referenced directly, it must be unique within + a component. By convention, id's should start with an uppercase letter. + + \code + Rectangle { + id: Root + color: "red" + width: GreenRect.width + 75 + height: Root.height + Rectangle { + color: "blue" + width: GreenRect.width + 25 + Rectangle { + id: GreenRect + color: "green" + width: 25 + height: Root.height + } + } + } + \endcode + + To relate id's back to QmlContext, id's exist as properties on the + component context. + + Bind expressions can reference any object property. The QML bind engine + relies on the presence of the NOTIFY signal in the Q_PROPERTY declaration + on a class to alert it that a property's value has changed. If this is + omitted, the bind expression can still access the property's value, but + the expression will not be updated if the value changes. The following is + an example of a QML friendly property declaration. + + \code + class Example : public QObject + { + Q_OBJECT + Q_PROPERTY(int sample READ sample WRITE setSample NOTIFY sampleChanged) + public: + int sample() const; + void setSample(int); + signals: + void sampleChanged(int); + }; + \endcode + + While generally no changes are needed to a C++ class to use property + binding, sometimes more advanced interaction between the binding engine and + an object is desirable. To facilitate this, there is a special exception + in the bind engine for allowing an object to access the binding directly. + + If a binding is assigned to a property with a type of QmlBindableValue + pointer (ie. QmlBindableValue *), each time the binding value changes, + a QmlBindableValue instance is assigned to that property. The + QmlBindableValue instance allows the object to read the binding and to + evaluate the binding's current value. + + \section1 Signal Properties + + In addition to reading and writing regular properties, QML allows you to + easily associate ECMAScript with signals. Consider the following example, + in which Button is a made-up type with a clicked() signal. + + \code + Button { + text: "Hello world!" + onClicked: print(text) + } + \endcode + + Clicking on the button causes "Hello world!" to be printed to the console + (or lost forever if you're running Windows). + + Like properties, signals automatically become available in QML without + any additional work. As illustrated signals are mapped into QML as special + "signal properties", using the name "on<Signal Name>" where the first + character of the signal's name is uppercased. If more than one signal of + the same name is exist on a class, only the first is available (see the + \l Connection element for more general signal connections). + + An important observation to make here is the lack of braces. While both + property bindings and signal properties involve executing ECMAScript code, + property bindings dynamically update the property value (hence the braces), + whereas with signal properties the constant script "value" is actually + assigned to the signal property. Trying to bind a value to a signal + property will not work! + + Signal parameters are also available to the executing script, as shown + below, as long as you remember to name the parameters of your signal + in C++ (see QMetaMethod::parameterNames()). + + \table + \row \o + \code + Example { + onDoSomething: for(var ii = 0; ii < count; ++ii) + print(message) + } + \endcode + \o + \code + class Example : public QObject + { + Q_OBJECT + signals: + void doSomething(int count, const QString &message); + }; + \endcode + \endtable + + Just like property bindings, signal scripts are executed in a context. The + signal script context is identical in scope to the "object context" under + property binding, with the exception that it has the signal parameters + bound in. + + In addition to scripts, it is possible to assign objects to signal properties. + This automatically connects the signal to the object's default method. A + default method is defined just like a default property, though the special + "DefaultMethod" class info. + + \code + Q_CLASSINFO("DefaultMethod", "myMethod(int)"); + \endcode + + This is useful in achieving several use cases, like that below which moves + the button when it is clicked. + + \code + Button { + id: MyButton + onClicked: NumberAnimation { + target: MyButton + property: "x" + to: 100 + } + } + \endcode + + If the class itself actually defines a property called "on<Name>", this will + be assigned the string value and the signal handling behaviour will be + disabled. + + \section1 Attached Properties + + Attached properties allow unrelated types to annotate another type with some + additional properties. Some APIs or operations are inherintly imperative, + and attached properties help out when translating these APIs into the + declarative QML language. + + Qt's QGridLayout is one such example. + + \code + QGridLayout { + QLabel { + QGridLayout.row: 0 + QGridLayout.column: 0 + text: "Name:" + } + QLineEdit { + QGridLayout.row: 0 + QGridLayout.column: 1 + } + + QLabel { + QGridLayout.row: 1 + QGridLayout.column: 0 + text: "Occupation:" + } + QLineEdit { + QGridLayout.row: 1 + QGridLayout.column: 1 + } + } + \endcode + + Attached properties are identified by the use of a type name, in the + case shown \c QGridLayout, as a grouped property specifier. To prevent + ambiguity with actual class instantiations, attached properties must + always be specified to include a period but can otherwise be used just like + regular properties. + + C++ types provide attached properties by declaring the public function \c qmlAttachedProperties like this example. + + \table + \row \o + \code + static QObject *Type::qmlAttachedProperties(QObject *); + \endcode + \o + \code + class Example : public QObject + { + Q_OBJECT + public: + static QObject *qmlAttachedProperties(QObject *); + }; + \endcode + \endtable + + When an attached property is accessed, the QML engine will call this method + to create an attachment object, passing in the object instance that the + attached property applies to. The attachment object should define all + the attached properties, and is generally parented to the provided object + instance to avoid memory leaks. The QML engine does not saves this object, + so it is not necessary for the attached property function to ensure that + multiple calls for the same instance object return the same attached object. + + While conceptually simple, implementing an attachment object is not quite + so easy. The \c qmlAttachedProperties function is static - attachment + objects are not associated with any particular instance. How the values + of the attached properties apply to the behaviour they are controlling is + entirely implementation dependent. An additional consequence of this is + that \bold any object can attach \bold any attached property. The following is + perfectly valid, although the attached property has no actual effect: + + \code + FancyGridLayout { + Item { + Button { + QGridLayout.row: 1 + } + } + } + \endcode + + The property has no effect because the (made-up) FancyGridLayout type defines the meaning + of the \c row attached property only to apply to its direct children. It + is possible that other types may have attached properties that affect + objects that aren't their direct children. + + Attached properties are an advanced feature that should be used with + caution. + + \note We may implement a convenience wrapper that makes using attached + properties easier for the common "attach to children" case. + + \section1 Property Value Sources + + Intrinsically, the QML engine can assign a property either a static value, + such as a number or an object tree, or a property binding. It is possible for + advanced users to extend the engine to assign other "types" of values to + properties. These "types" are known as property value sources. + + Consider the following example. + + \code + Rectangle { + x: NumberAnimation { running: true; repeat; true; from: 0; to: 100; } + } + \endcode + + Here the \c x property of the rectangle will be animated from 0 to 100. + To support this, the NumberAnimation class inherits the + QmlPropertyValueSource class. If a type inherits this class and is assigned + to a property for which type assignment would otherwise fail (ie. the + property itself doesn't have a type of QmlPropertyValueSource *), the QML + engine will automatically set the property as the target of the value + source. + + \section1 Parser Status + + Generally using QML is a breeze - you implement your classes in C++, add + the appropriate properties, signals and slots and off you go. The QML + engine takes care of instantiating your classes and setting the properties + and everything works fine. + + However, sometimes it is helpful to know a little more about the status of + the QML parser. For example, it might be beneficial from a performance + standpoint to delay initializing some data structures until all the + properties have been set. + + To assist with this, the QML engine defines an interface class called + QmlParserStatus. The interface defines a number of virtual methods that are + invoked at various stages of the component instantiation. To receive + these notifications, all a class has to do is to inherit the interface, and + notify the Qt meta system using the Q_INTERFACES() macro. For example, + + \code + class Example : public QObject, public QmlParserStatus + { + Q_OBJECT + Q_INTERFACES(QmlParserStatus) + public: + virtual void componentComplete() + { + qDebug() << "Woohoo! Now to do my costly initialization"; + } + }; + \endcode + + \section1 Extended Type Definitions + + QML requires that types have the appropriate properties and signals to + work well within the declarative environment. In the case of existing + types, it is sometimes necessary to add signals, properties or slots to a + target class to make it more QML friendly but the original type cannot be + modified. For these cases, the QML engine supports extended type + definitions. + + An extended type definition allows the programmer to supply an additional + type - known as the extension type - when registering the target class + whose properties, signals and slots are transparently merged with the + original target class when used from within QML. + + An extension class is a regular QObject, with a constructor that takes a + QObject pointer. When needed (extension classes are delay created + until the first extension attribute is accessed) the extension + class is created and the target object is passed in as the parent. When + an extension attribute on the original is accessed, the appropriate signal, + property or slots on the extension object is used instead. + + When an extended type is installed, the + \code + #define QML_DEFINE_EXTENDED_TYPE(T,QmlName,ExtendedTypeName) + \endcode + macro should be used instead of the regular \c QML_DEFINE_TYPE. + + This example shows the addition of a read-only \c textLength property to + QLabel being implemented as an extension. + + \table + \row + \o + \code + class QLabelExtension : public QObject + { + Q_OBJECT + Q_PROPERTY(int textLength READ textLength) + public: + QWidgetExtension(QObject *parent) : QObject(parent) {} + int textLength() const { + return static_cast<QLabel *>(parent())->text().count(); + } + }; + QML_DEFINE_EXTENDED_TYPE(QLabel,QLabel,QLabelExtension); + \endcode + \o + \code + QLabel { + id: Label1 + text: "Hello World!" + } + QLabel { + text: "Label1 text length: " + Label1.textLength + } + \endcode + \endtable + + Attributes defined through extensions are inherited, just like attributes + defined on a normal class. Any types that inherit from \c QLabel, will + also have the \c textLength property. Derived types can include additional + extensions which are merged together, but only a single extension can be + specified for each single C++ class. + + Extended type definitions can even be used to add an attached properties + function to a type - just declare the \c qmlAttachedProperties function on + the extension object. + +*/ + diff --git a/doc/src/declarative/qmlformat.qdoc b/doc/src/declarative/qmlformat.qdoc new file mode 100644 index 0000000..9cfebf0 --- /dev/null +++ b/doc/src/declarative/qmlformat.qdoc @@ -0,0 +1,184 @@ +/*! +\page qmlformat.html +\title QML Format Reference + +\tableofcontents + +\section1 Overview + +QML is an extension to \l {http://www.ecma-international.org/publications/standards/Ecma-262.htm} +{ECMAScript}. QML adds a mechanism for declaratively building a tree of objects, improved +integration between ECMAScript and Qt's existing QObject based type system, and support for +transparently maintained property value bindings between ECMAScript expressions and QObject +properties. + +Much of a QML file consists of valid ECMAScript \e {Statement}s. Except where constraints imposed +by ECMAScript, C++ or QObject prevented it, the syntactic extensions introduced by QML are designed +to look similar and fit well with existing ECMAScript syntax and concepts. + +\section2 Commenting + +The commenting rules in QML are the same as for ECMAScript. Both \e {MultiLineComment} blocks and \e {SingleLineComment}'s are supported. + +\section1 Definitions + +\e {QML interpreter}: QmlEngine + +\e {QML execution context}: QmlContext + +\e {inherited characteristic} + +\section1 QML Document + +\section2 Syntax + +\e {QMLDocument} \bold {:} + +\quotation +\e {QMLImportList} \sub {opt} \e {QMLObjectDefinition} +\endquotation + +\e {QMLImportList} \bold {:} +\quotation +\e {QMLImportStatement} \e {QMLImportList} \sub {opt} +\endquotation + +\e {QMLImportStatement} \bold {:} + +\quotation +\bold {import} \e {StringLiteral} + +\bold {import} \e {StringLiteral} \e {QMLVersionNumber} + +\bold {import} \e {QMLNamespaceName} \e {QMLVersionNumber} + +\bold {import} \e {StringLiteral} \bold {as} \e {QMLNamespacePrefix} + +\bold {import} \e {StringLiteral} \e {QMLVersionNumber} \bold {as} \e {QMLNamespacePrefix} + +\bold {import} \e {QMLNamespaceName} \e {QMLVersionNumber} \bold {as} \e {QMLNamespacePrefix} +\endquotation + +\e {QMLNamespaceName} \bold {:} +\quotation +\e {QMLQualifiedId} +\endquotation + +\e {QMLVersionNumber} \bold {:} +\quotation +\e {DecimalLiteral} \bold {but not} with \e {ExponentPart} +\endquotation + +\section2 Semantics + +A QML document is the unit in which QML code may be passed to the QML interpreter. A QML document +is syntactically self contained. QML documents are evaluated by the QML interpreter in a QML +execution context to produce a single instantiated object of the type specified by +\e {QMLObjectDefinition}. + +The \e {QMLImportList} is used to statically resolve type references used within the enclosing +QML document. The import list is \bold {not} an \e {inherited characteristic}; its scope of +influence is limited to structures logically contained by the document. + +An import statement is used to bring a set of types into scope for a QML document. + +\section1 Object Definition + +\section2 Syntax + +\e {QMLObjectDefinition} \bold {:} +\quotation +\e {QMLQualifiedId} \bold {\{} \e {QMLObjectMemberList} \bold {\}} +\endquotation + +\e {QMLObjectMemberList} \bold {:} +\quotation +\e {QMLObjectMember} \e {QMLObjectMemberList} \sub {opt} +\endquotation + +\e {QMLObjectMember} \bold {:} +\quotation +\e {QMLMemberAssignment} + +\e {QMLObjectDefinition} + +\e {QMLObjectExtensionDefinition} +\endquotation + +\e {QMLMemberAssignmentList} \bold {:} +\quotation +\e {QMLMemberAssignment} \e {QMLMemberAssignmentList} \sub {opt} +\endquotation + +\e {QMLMemberAssignment} \bold {:} +\quotation + +\e {QMLQualifiedId} \bold {:} \e {Literal} \bold {but not} \e {NullLiteral} + +\e {QMLQualifiedId} \bold {:} \e {QMLObjectDefinition} + +\e {QMLQualifiedId} \bold {:} \e {QMLObjectDefinitionArray} + +\e {QMLQualifiedId} \bold {:} \e {QMLBindingExpression} + +\e {QMLQualifiedId} \bold {\{} \e {QMLMemberAssignmentList} \bold {\}} + +\endquotation + +\section2 Semantics + +\section1 Object Extension + +\section2 Syntax + +\e {QMLObjectExtensionDefinition} \bold {:} +\quotation +\e {QMLObjectPropertyDefinition} + +\e {QMLObjectSignalDefinition} + +\e {QMLObjectMethodDefinition} +\endquotation + +\e {QMLObjectPropertyDefinition} \bold {:} +\quotation +\bold {property} \e {QmlObjectPropertyType} \e {QMLMemberIdentifier} + +\bold {default} \bold {property} \e {QmlObjectPropertyType} \e {QMLMemberIdentifier} + +\bold {property} \e {QmlObjectPropertyType} \e {QMLMemberIdentifier} \bold {:} \e {Literal} \bold {but not} \e {NullLiteral} + +\bold {property} \e {QmlObjectPropertyType} \e {QMLMemberIdentifier} \bold {:} \e {QmlBindingExpression} + +\bold {default} \bold {property} \e {QmlObjectPropertyType} \e {QMLMemberIdentifier} \bold {:} \e {Literal} \bold {but not} \e {NullLiteral} + +\bold {default} \bold {property} \e {QmlObjectPropertyType} \e {QMLMemberIdentifier} \bold {:} \e {QmlBindingExpression} +\endquotation + +\e {QMLObjectPropertyType} \bold {:: one of} +\quotation +\bold {int} \bold {bool} \bold {double} \bold {real} \bold {string} \bold {url} \bold {color} \bold {date} \bold {var} \bold {variant} \bold {alias} +\endquotation + +\e {QMLObjectSignalDefinition} \bold {:} +\quotation +\bold {signal} \e {QMLMemberIdentifier} + +\bold {signal} \e {QMLMemberIdentifier} \bold {(} QMLMemberTypedParameterList \bold {)} +\endquotation + +\e {QMLObjectMethodDefinition} \bold {:} +\quotation +\e {FunctionDeclaration} \bold {but not} \e {Identifier} \sub {opt} +\endquotation +\section2 Semantics + +\section1 Binding Expression + +\section2 Syntax + +\e {QMLBindingExpression} \bold {:} + +\section2 Semantics + +*/ diff --git a/doc/src/declarative/qmlintro.qdoc b/doc/src/declarative/qmlintro.qdoc new file mode 100644 index 0000000..3d167ac --- /dev/null +++ b/doc/src/declarative/qmlintro.qdoc @@ -0,0 +1,229 @@ +/*! +\page qmlintroduction.html +\title Introduction to the QML language + +\tableofcontents + +\section1 What is QML? + +QML is a declarative language designed to describe the user interface of a +program: both what it looks like and how it behaves. In QML, a user +interface is specified as a tree of objects with properties. + +\section1 What should I know before starting? + +This introduction is meant for those with little or no programming +experience. JavaScript is used as a scripting language in QML, so you may want +to learn a bit more about it (\l{JavaScript: The Definitive Guide}) before diving +too deep into QML. It's also helpful to have a basic understanding of other web +technologies like HTML and CSS, but not required. + +\section1 Basic QML Syntax + +QML looks like this: + +\code +Rectangle { + width: 200 + height: 200 + color: "white" + Image { + source: "pics/logo.png" + anchors.centerIn: parent + } +} +\endcode + +Objects are specified by their type, followed by a pair of braces. Object +types always begin with a capital letter. In the above example, there are +two objects, a \l Rectangle, and an \l Image. Between the braces, we can specify +information about the object, such as its properties. + +Properties are specified as \c {property: value} (much like CSS). In the above +example, we can see the Image has a property named \e source, which has been +assigned the value \e "pics/logo.png". The property and its value are +separated by a colon. + +Properties can be specified one-per-line: + +\code +Rectangle { + width: 100 + height: 100 +} +\endcode + +or you can put multiple properties on a single line: + +\code +Rectangle { width: 100; height: 100 } +\endcode + +When multiple property/value pairs are specified on a single line, they +must be separated by a semicolon. + +\section1 Expressions + +In addition to assigning values to properties, you can also assign +expressions written in JavaScript. + +\code +Rotation { angle: 360*3 } +\endcode + +These expressions can include references to other objects and properties, in which case +a \e binding is established: when the value of the expression changes, the property the +expression has been assigned to is automatically updated to that value. + +\code +Item { + Text { + id: Text1 + text: "Hello World" + } + Text { + id: Text2 + text: Text1.text + } +} +\endcode + +In the example above, the Text2 object will display the same text as Text1. If Text1 is updated, +Text2 will be updated as well. + +Note that to refer to other objects, we use their \e id (more information on the id property can be +found in a following section). + +\section1 QML Comments + +Commenting in QML is similar to JavaScript. +\list +\o Single line comments begin with // and end at the end of the line. +\o Multiline comments begin with /* and end with *\/ +\endlist + +\quotefile doc/src/snippets/declarative/comments.qml + +Comments are ignored by the engine. The are useful for explaining what you +are doing: for referring back to at a later date, or for others reading +your QML files. + +Comments can also be used to prevent the execution of code, which is +sometimes useful for tracking down problems. + +\code +Text { + text: "Hello world!" + //opacity: 0.5 +} +\endcode + +In the above example, the Text object will have normal opacity, since the +line opacity: 0.5 has been turned into a comment. + +\section1 Properties + +\section2 Property naming + +Properties begin with a lowercase letter (with the exception of \l{Attached Properties}). + +\section2 Property types + +QML supports properties of many types (\l{Common QML Types}). The basic types include int, +real, bool, string, color, and lists. + +\code +Item { + x: 10.5 // a 'real' property + ... + state: "Details" // a 'string' property + focus: true // a 'bool' property +} +\endcode + +QML properties are what is known as \e typesafe. That is, they only allow you to assign a value that +matches the property type. For example, the scale property of item is a real, and if you try to assign +a string to it you will get an error. + +\badcode +Item { + scale: "hello" //illegal! +} +\endcode + +\section3 The 'id' property + +The \c id property is a special property of type \e id. Assigning an id to an object allows you +to refer to it elsewhere. + +\code +Item { + Text { + id: MyName + text: "..." + } + Text { + text: MyName.text + } +} +\endcode + +\c ids must begin with a letter. We recommend that you start your ids with a capital letter. + +\section2 List properties + +List properties look like this: + +\code +Item { + children: [ + Image {}, + Text {} + ] +} +\endcode + +The list is enclosed in square brackets, with a comma separating the +list elements. In cases where you are only assigning a single item to a +list, you can omit the square brackets: + +\code +Image { + children: Rectangle {} +} +\endcode + +\section2 Default properties + +Each object type can specify one of its list properties as its default property. +If a list property has been declared as the default property, the property tag can be omitted. + +For example this code: +\code +State { + changes: [ + PropertyChanges {}, + PropertyChanges {} + ] +} +\endcode + +can be simplified to: + +\code +State { + PropertyChanges {} + PropertyChanges {} +} +\endcode + +because \c changes is the default property of the \c State type. + +\section2 Dot Properties + +\section2 Attached Properties +\target attached-properties + +\section2 Signal Handlers + +*/ diff --git a/doc/src/declarative/qmlreference.qdoc b/doc/src/declarative/qmlreference.qdoc new file mode 100644 index 0000000..8a50547 --- /dev/null +++ b/doc/src/declarative/qmlreference.qdoc @@ -0,0 +1,41 @@ +/*! + \page qmlreference.html + \title QML Reference + + \target qtdeclarativemainpage + + QML is a language for building highly dynamic and fluid applications. It is targetted at the sorts of user + interface (and the sorts of hardware) in embedded devices such as phones, media + players, and set-top boxes. It is also appropriate for highly custom desktop + user-interfaces, or special elements in more traditional desktop + user-interfaces. + + Building fluid applications is done declaratively, rather than procedurally. + That is, you specify \e what the UI should look like and how it should behave + rather than specifying step-by-step \e how to build it. Specifying a UI declaratively + does not just include the layout of the interface items, but also the way each + individual item looks and behaves and the overall flow of the application. + + Getting Started: + \list + \o \l {qmlexamples}{Examples} + \o \l {tutorial}{Tutorial: 'Hello World'} + \o \l {tutorials-declarative-contacts.html}{Tutorial: 'Introduction to QML'} + \o \l {Introduction to the QML language} (in progress) + \endlist + + Core Features: + \list + \o \l {binding}{Data Binding} + \o \l {anchor-layout}{Layout Anchors} + \o \l {qmlanimation}{Animation} + \o \l {components}{Components} + \o \l {qmlmodules}{Modules} + \o \l {qmlfocus}{Keyboard Focus} + \endlist + + QML Reference: + \list + \o \l {elements}{QML Elements} + \endlist +*/ diff --git a/doc/src/declarative/qmlviewer.qdoc b/doc/src/declarative/qmlviewer.qdoc new file mode 100644 index 0000000..8228737 --- /dev/null +++ b/doc/src/declarative/qmlviewer.qdoc @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qmlviewer.html + \title Qt Declarative UI Viewer (qmlviewer) + \ingroup qttools + \keyword qmlviewer + + This page documents the \e{Declarative UI Viewer} for the Qt GUI + toolkit. The \c qmlviewer reads a declarative user interface definition + (\c .qml) file and displays the user interface it describes. + + \section1 Options + + When run with the \c -help option, qmlviewer shows available options. + + \section1 Dummy Data + + One use of qmlviewer is to allow QML files to be viewed stand-alone, + rather than being loaded from within a Qt program. Qt applications will + usually bind objects and properties into the execution context before + running the QML. To stand-in for such bindings, you can provide dummy + data: create a directory called "dummydata" in the same directory as + the target QML file and create files there with the "qml" extension. + All such files will be loaded as QML objects and bound to the root + context as a property with the name of the file (without ".qml"). + + For example, if the Qt application has a "clock.time" property + that is a qreal from 0 to 86400 representing the number of seconds since + midnight, dummy data for this could be provided by \c dummydata/clock.qml: + \code + Object { property real time: 12345 } + \endcode + Any QML can be used in the dummy data files. You could even animate the + fictional data! +*/ diff --git a/doc/src/declarative/qtdeclarative.qdoc b/doc/src/declarative/qtdeclarative.qdoc new file mode 100644 index 0000000..1b7644c --- /dev/null +++ b/doc/src/declarative/qtdeclarative.qdoc @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \module QtDeclarative + \title QtDeclarative Module + \ingroup modules + + \brief The Qt Declarative module provides a declarative framework for building + highly dynamic and fluid applications. + + Qt Declarative is targetted at the sorts of user + interface (and the sorts of hardware) in embedded devices such as phones, media + players, and set-top boxes. It is also appropriate for highly custom desktop + user-interfaces, or special elements in more traditional desktop + user-interfaces. + + Building fluid applications is done declaratively, rather than procedurally. + That is, you specify \e what the UI should look like and how it should behave + in an declarative format called QML, rather than specifying step-by-step \e how to + build it in a language like C++ or JavaScript. Specifying a UI declaratively + does not just include the layout of the interface items, but also the way each + individual item looks and behaves and the overall flow of the application. + + Getting Started: + \list + \o \l {qmlexamples}{Examples} + \o \l {tutorial}{Tutorial: 'Hello World'} + \o \l {tutorials-declarative-contacts.html}{Tutorial: 'Introduction to QML'} + \o \l {qmlforcpp}{QML For C++ Programmers} + \endlist + + Core QML Features: + \list + \o \l {binding}{Data Binding} + \o \l {anchor-layout}{Layout Anchors} + \o \l {qmlanimation}{Animation} + \o \l {qmlmodules}{Modules} + \o \l {qmlfocus}{Keyboard Focus} + \o \l {Extending types from QML} + \endlist + + QML Reference: + \list + \o \l {QML Format} + \o \l {elements}{QML Elements} + \endlist + + C++ Reference: + \list + \o \l {Extending QML} + \o \l {qtbinding}{QML/C++ Data Binding} + \o \l {cppitem}{C++ Components} + \endlist +*/ diff --git a/doc/src/declarative/qtprogrammers.qdoc b/doc/src/declarative/qtprogrammers.qdoc new file mode 100644 index 0000000..742fc07 --- /dev/null +++ b/doc/src/declarative/qtprogrammers.qdoc @@ -0,0 +1,124 @@ +/*! + + INCOMPLETE + +\page qtprogrammers.html +\target qtprogrammers +\title QML for Qt programmers + +\section1 Overview + +While QML does not require Qt knowledge to use, if you \e are already familar with Qt, +much of your knowledge is directly relevant to learning and using QML. Of course, +an application with a UI defined in QML also uses Qt for all the non-UI logic. + +\section1 Familiar Concepts + +QML provides direct access to the following concepts from Qt: + +\list + \o QAction - the \l {basicqmlaction}{action} type + \o QObject signals and slots - available as functions to call in JavaScript + \o QObject properties - available as variables in JavaScript + \o QWidget - QFxView is a QML-displaying widget + \o Qt models - used directly in data binding (QAbstractItemModel and next generation QListModelInterface) +\endlist + +Qt knowledge is \e required for \l {cppitem}{writing elements in C++}. + + +\section1 QML Items compared with QWidgets + +QML Items are very similar to QWidgets: they define the look and feel of the user interface. (Note that while QWidgets +haven't traditionally been used to define the look and feel of view delegates, QML Items can be used for this as well.) + +There are three structurally different types of QWidget: + +\list + \o Simple widgets that are not used as parents (QLabel, QCheckBox, QToolButton, etc.) + \o Parent widgets that are normally used as parents to other widgets (QGroupBox, QStackedWidget, QTabWidget, etc.) + \o Compound widgets that are internally composed of child widgets (QComboBox, QSpinBox, QFileDialog, QTabWidget, etc.) +\endlist + +QML Items also serve these purposes. Each is considered separately below. + +\section2 Simple Widgets + +The most important rule to remember while implementing a new QFxItem in C++ +is that it should not contain any look and feel policies - leave that to the +QML usage of the item. + +As an example, imagine you wanted a reusable Button item. If you therefore +decided to write a QFxItem subclass to implement a button, +just as QToolButton subclasses QWidget for this purpose, following the rule above, your +\c QFxButton would not have any appearance - just the notions of enabled, triggering, etc. + +But there is already an object in Qt that does this: QAction. + +QAction is the UI-agnostic essence of QPushButton, QCheckBox, QMenu items, QToolButton, +and other visual widgets that are commonly bound to a QAction. + +So, the job of implementing a checkbox abstraction for QML is already done - it's QAction. +The look and feel of an action - the appearance of the button, the transition between states, +and exactly how it respond to mouse, key, or touch input, should all be left for definition +in QML. + +It is illustrative to note that QFxTextEdit is built upon QTextControl, +QFxWebView is built upon QWebPage, and ListView uses QListModelInterface, +just as QTextEdit, QWebView, and QListView are built upon +those same UI-agnostic components. + +The encapsulation of the look and feel that QWidgets gives is important, and for this +the QML concept of \l components serves the same purpose. If you are building a complete +suite of applications which should have a consistent look and feel, you should build +a set of reusable components with the look and feel you desire. + +So, to implement your reusable button, you would simply build a QML component. + + +\section2 Parent Widgets + +Parent widgets each provide a generic way to interface to one or more arbitrary other widgets. +A QTabWidget provides an interface to multiple "pages", one of which is visible at any time, +and a mechnism for selecting among them (the QTabBar). A QScollArea provides scrollbars around +a widget that is otherwise too large to fit in available space. + +Nearly all such components can be created directly in QML. Only a few cases +which require very particular event handling, such as Flickable, require C++ implementations. + +As an example, imagine you decided to make a generic tab widget item to be used +through your application suite wherever information is in such quantity that it +needs to be divided up into pages. + +To do this in QML, ... \todo example of container definition. + +A significant difference in the parenting concept with QML compare to QWidgets +is that while child items are positioned relative to their parents, +there is no requirement that they be wholy contained ("clipped") to +the parent (although the clipped property of the child Item does allow +this where it is needed). +This difference has rather far-reaching consequences, for example: + +\list + \o A shadow or highlight around a widget could be a child of that widget. + \o Particle effects can flow outside the object where they originate. + \o Transitioning animations can "hide" items by visibly moving them beyond the screen bounds. +\endlist + + +\section2 Compound Widgets + +Some widgets provide functionality by composing other widgets as an "implementation detail", +providing a higher level API to the composition. QSpinBox for example is a line edit and some +buttons to increase/decrease the edited value. QFileDialog uses a whole host of widgets to +give the user a way of finding and selecting a file name. + +When developing reusable QML Items, you may choose to do the same: build an item composed +of other items you have already defined. + +The only caveat when doing this is to consider the possible animations and transitions that +users of the compound item might wish to employ. For example, a spinbox might need to smoothly +transition from an arbitrary Text item, or characters within a Text item, so your spinbox +item would need to be sufficiently flexible to allow such animation. + +*/ diff --git a/doc/src/declarative/tutorial.qdoc b/doc/src/declarative/tutorial.qdoc new file mode 100644 index 0000000..a2a34b9 --- /dev/null +++ b/doc/src/declarative/tutorial.qdoc @@ -0,0 +1,19 @@ +/*! +\page tutorial.html +\title Tutorial + +This tutorial gives an introduction to QML. It doesn't cover everything; the emphasis is on teaching the key principles, and features are introduced as needed. + +Chapter one starts with a minimal "Hello world" program and the following chapters introduce new concepts. + +The tutorial's source code is located in the $QTDIR/examples/declarative/tutorials/helloworld directory. + +Tutorial chapters: + +\list +\o \l {tutorial1}{Tutorial 1} +\o \l {tutorial2}{Tutorial 2} +\o \l {tutorial3}{Tutorial 3} +\endlist + +*/ diff --git a/doc/src/declarative/tutorial1.qdoc b/doc/src/declarative/tutorial1.qdoc new file mode 100644 index 0000000..d4f1095 --- /dev/null +++ b/doc/src/declarative/tutorial1.qdoc @@ -0,0 +1,78 @@ +/*! +\page tutorial1.html +\title Tutorial 1 - Hello World! +\target tutorial1 + +This first program is a simple "Hello world" example. The picture below is a screenshot of this program. + +\image declarative-tutorial1.png + +Here is the QML code for the application: + +\code +Rectangle { + id: Page + width: 480 + height: 200 + color: "LightGrey" + Text { + id: HelloText + text: "Hello world!" + font.pointSize: 24 + font.bold: true + y: 30 + anchors.horizontalCenter: Page.horizontalCenter + } +} +\endcode + +\section1 Walkthrough + +\section2 Rectangle element + +\code +Rectangle { + id: Page + width: 480 + height: 200 + color: "LightGrey" +} +\endcode + +First, we declare a root element of type \l Rectangle. It is one of the basic building blocks you can use to create an application in QML. +We give it an id to be able to refer to it later. In this case, we call it \e Page. We also set the \c width, \c height and \c color properties. +The \l Rectangle element contains many other properties (such as \c x and \c y), but these are left at their default values. + +\section2 Text element + +\code +Text { + id: HelloText + text: "Hello world!" + font.pointSize: 24 + font.bold: true + y: 30 + anchors.horizontalCenter: Page.horizontalCenter +} +\endcode + +We add a text element as a child of our root element to display the text 'Hello world!'. + +The \c y property is used to position the text vertically at 30 pixels from the top of its parent. + +The \c font.pointSize and \c font.bold properties are related to fonts and use the \e 'dot' notation. + +The \c anchors.horizontalCenter property refers to the horizontal center of an element. In this case, we specify that our text element should be horizontally centered in the \e Page element. + +\section2 Viewing the example + +To view what you have created, run the qmlviewer (located in the \c bin directory) with your filename as the first argument. For example, to run the provided completed Tutorial 1 example from the install location, you would type: + +\code +bin/qmlviewer $QTDIR/examples/declarative/tutorials/helloworld/t1/tutorial1.qml +\endcode + +[\l tutorial] [Next: \l tutorial2] + +*/ + diff --git a/doc/src/declarative/tutorial2.qdoc b/doc/src/declarative/tutorial2.qdoc new file mode 100644 index 0000000..c6fd06b --- /dev/null +++ b/doc/src/declarative/tutorial2.qdoc @@ -0,0 +1,132 @@ +/*! +\page tutorial2.html +\title Tutorial 2 - Some colors +\target tutorial2 + +This chapter adds a color picker to change the color of the text. + +\image declarative-tutorial2.png + +Our color picker is made of many cells with different colors. To avoid writing the same code many times, we first create a new \c Cell component with a color property (see \l components). + +Here is the QML code for \c Cell.qml: + +\code +Item { + property var color + + id: CellContainer + width: 40 + height: 25 + + Rectangle { + anchors.fill: parent + color: CellContainer.color + } + MouseRegion { + anchors.fill: parent + onClicked: { HelloText.color = CellContainer.color } + } +} +\endcode + +Then, we use our \c Cell component to create the color picker in the QML code for the application: + +\code +Rectangle { + id: Page + width: 480 + height: 200 + color: "LightGrey" + Text { + id: HelloText + text: "Hello world!" + font.pointSize: 24 + font.bold: true + y: 30 + anchors.horizontalCenter: Page.horizontalCenter + } + Grid { + id: ColorPicker + x: 0 + anchors.bottom: Page.bottom + width: 120; height: 50 + rows: 2; columns: 3 + Cell { color: "#ff0000" } + Cell { color: "#00ff00" } + Cell { color: "#0000ff" } + Cell { color: "#ffff00" } + Cell { color: "#00ffff" } + Cell { color: "#ff00ff" } + } +} +\endcode + +\section1 Walkthrough + +\section2 The Cell Component + +\code +Item { + id: CellContainer + width: 40 + height: 25 +} +\endcode + +The root element of our component is an \c Item. It is the most basic element in QML and is often used as a container for other elements. + +\code +property var color +\endcode + +We declare a \c color property. This property is accessible from \e outside our component, this allows us to instantiate the cells with different colors. + +\code +Rectangle { + anchors.fill: parent + color: CellContainer.color +} +\endcode + +Our cell component is basically a colored rectangle. + +The \c anchors.fill property is a convenient way to set the size of an element. In this case the \c Rectangle will have the same size as its parent. + +We bind the \c color property of this \c Rectangle to the color property of our component. + +\code +MouseRegion { + anchors.fill: parent + onClicked: { HelloText.color = CellContainer.color } +} +\endcode + +In order to change the color of the text when clicking on a cell, we create a \c MouseRegion element with the same size as its parent. + +The \c onClicked property sets the \c color property of the element named \e HelloText to our cell color. + +\section2 The main QML file + +\code +Grid { + id: ColorPicker + x: 0 + anchors.bottom: Page.bottom + width: 120; height: 50 + rows: 2; columns: 3 + Cell { color: "#ff0000" } + Cell { color: "#00ff00" } + Cell { color: "#0000ff" } + Cell { color: "#ffff00" } + Cell { color: "#00ffff" } + Cell { color: "#ff00ff" } +} +\endcode + +In the main QML file, the only thing we have to do is to create a color picker by putting 6 cells with different colors in a grid. + +[Previous: \l tutorial1] [Next: \l tutorial3] + +*/ + diff --git a/doc/src/declarative/tutorial3.qdoc b/doc/src/declarative/tutorial3.qdoc new file mode 100644 index 0000000..a0d842c --- /dev/null +++ b/doc/src/declarative/tutorial3.qdoc @@ -0,0 +1,115 @@ +/*! +\page tutorial3.html +\title Tutorial 3 - States +\target tutorial3 + +In this chapter, we make this example a little bit more dynamic by introducing states. + +We want our text to jump at the bottom of the screen and become red when clicked. + +\image declarative-tutorial3_animation.gif + +Here is the QML code: + +\code +Rectangle { + id: Page + width: 480 + height: 200 + color: "LightGrey" + Text { + id: HelloText + text: "Hello world!" + font.pointSize: 24 + font.bold: true + y: 30 + anchors.horizontalCenter: Page.horizontalCenter + states: [ + State { + name: "down" + when: MouseRegion.pressed == true + PropertyChanges { target: HelloText; y: 160; color: "red" } + } + ] + transitions: [ + Transition { + from: "*" + to: "down" + reversible: true + ParallelAnimation { + NumberAnimation { + properties: "y" + duration: 500 + easing: "easeOutBounce" + } + ColorAnimation { property: "color"; duration: 500 } + } + } + ] + } + MouseRegion { id: MouseRegion; anchors.fill: HelloText } + Grid { + id: ColorPicker + x: 0 + anchors.bottom: Page.bottom + width: 120; height: 50 + rows: 2; columns: 3 + Cell { color: "#ff0000" } + Cell { color: "#00ff00" } + Cell { color: "#0000ff" } + Cell { color: "#ffff00" } + Cell { color: "#00ffff" } + Cell { color: "#ff00ff" } + } +} +\endcode + +\section1 Walkthrough + +\code +states: [ + State { + name: "down" + when: MouseRegion.pressed == true + PropertyChanges { target: HelloText; y: 160; color: "red" } + } +] +\endcode + +First, we create a new state \e down for our text element. This state will be activated when MouseRegion is pressed, and deactivated when it is released. + +The \e down state includes a set of property changes from our implicit \e {default state} (the items as they were initially defined in the QML). Specifically, we set the \c y property of the text to 160 and the \c color to red. + +\code +Transition { + from: "*" + to: "down" + reversible: true +} +\endcode + +Because we don't want the text to appear at the bottom instantly but rather move smoothly, we add a transition between our two states. + +\c from and \c to define the states between which the transition will run. In this case, we want a transition from any state to our \e down state. + +Because we want the same transition to be run in reverse when changing back from the \e down state to the default state, we set \c reversible to \c true. This is equivalent to writing the two transitions separately. + +\code +ParallelAnimation { + NumberAnimation { + properties: "y" + duration: 500 + easing: "easeOutBounce" + } + ColorAnimation { property: "color"; duration: 500 } +} +\endcode + +The \c ParallelAnimation element makes sure that the two animations (color and position) will start at the same time. We could also run them one after the other by using \c SequentialAnimation instead. + +For more details on states and transitions, see \l {states-transitions}{States and Transitions}. + +[Previous: \l tutorial2] [\l tutorial] + +*/ + diff --git a/doc/src/images/declarative-anchors_example.png b/doc/src/images/declarative-anchors_example.png Binary files differnew file mode 100644 index 0000000..293cd4b --- /dev/null +++ b/doc/src/images/declarative-anchors_example.png diff --git a/doc/src/images/declarative-anchors_example2.png b/doc/src/images/declarative-anchors_example2.png Binary files differnew file mode 100644 index 0000000..6d3be7d --- /dev/null +++ b/doc/src/images/declarative-anchors_example2.png diff --git a/doc/src/images/declarative-image_fillMode.gif b/doc/src/images/declarative-image_fillMode.gif Binary files differnew file mode 100644 index 0000000..eb0a9af --- /dev/null +++ b/doc/src/images/declarative-image_fillMode.gif diff --git a/doc/src/images/declarative-image_tile.png b/doc/src/images/declarative-image_tile.png Binary files differnew file mode 100644 index 0000000..b946a6d --- /dev/null +++ b/doc/src/images/declarative-image_tile.png diff --git a/doc/src/images/declarative-item_opacity1.png b/doc/src/images/declarative-item_opacity1.png Binary files differnew file mode 100644 index 0000000..cde973b --- /dev/null +++ b/doc/src/images/declarative-item_opacity1.png diff --git a/doc/src/images/declarative-item_opacity2.png b/doc/src/images/declarative-item_opacity2.png Binary files differnew file mode 100644 index 0000000..8627360 --- /dev/null +++ b/doc/src/images/declarative-item_opacity2.png diff --git a/doc/src/images/declarative-item_stacking1.png b/doc/src/images/declarative-item_stacking1.png Binary files differnew file mode 100644 index 0000000..18f4148 --- /dev/null +++ b/doc/src/images/declarative-item_stacking1.png diff --git a/doc/src/images/declarative-item_stacking2.png b/doc/src/images/declarative-item_stacking2.png Binary files differnew file mode 100644 index 0000000..7a71bcd --- /dev/null +++ b/doc/src/images/declarative-item_stacking2.png diff --git a/doc/src/images/declarative-item_stacking3.png b/doc/src/images/declarative-item_stacking3.png Binary files differnew file mode 100644 index 0000000..cde973b --- /dev/null +++ b/doc/src/images/declarative-item_stacking3.png diff --git a/doc/src/images/declarative-item_stacking4.png b/doc/src/images/declarative-item_stacking4.png Binary files differnew file mode 100644 index 0000000..3fdf627 --- /dev/null +++ b/doc/src/images/declarative-item_stacking4.png diff --git a/doc/src/images/declarative-nopercent.png b/doc/src/images/declarative-nopercent.png Binary files differnew file mode 100644 index 0000000..28b00a9 --- /dev/null +++ b/doc/src/images/declarative-nopercent.png diff --git a/doc/src/images/declarative-pathattribute.png b/doc/src/images/declarative-pathattribute.png Binary files differnew file mode 100644 index 0000000..57cd049 --- /dev/null +++ b/doc/src/images/declarative-pathattribute.png diff --git a/doc/src/images/declarative-pathcubic.png b/doc/src/images/declarative-pathcubic.png Binary files differnew file mode 100644 index 0000000..ffbca5d --- /dev/null +++ b/doc/src/images/declarative-pathcubic.png diff --git a/doc/src/images/declarative-pathquad.png b/doc/src/images/declarative-pathquad.png Binary files differnew file mode 100644 index 0000000..65f1999 --- /dev/null +++ b/doc/src/images/declarative-pathquad.png diff --git a/doc/src/images/declarative-percent.png b/doc/src/images/declarative-percent.png Binary files differnew file mode 100644 index 0000000..c277055 --- /dev/null +++ b/doc/src/images/declarative-percent.png diff --git a/doc/src/images/declarative-qtlogo1.png b/doc/src/images/declarative-qtlogo1.png Binary files differnew file mode 100644 index 0000000..940d159 --- /dev/null +++ b/doc/src/images/declarative-qtlogo1.png diff --git a/doc/src/images/declarative-qtlogo2.png b/doc/src/images/declarative-qtlogo2.png Binary files differnew file mode 100644 index 0000000..b1d128a --- /dev/null +++ b/doc/src/images/declarative-qtlogo2.png diff --git a/doc/src/images/declarative-qtlogo3.png b/doc/src/images/declarative-qtlogo3.png Binary files differnew file mode 100644 index 0000000..d516524 --- /dev/null +++ b/doc/src/images/declarative-qtlogo3.png diff --git a/doc/src/images/declarative-qtlogo4.png b/doc/src/images/declarative-qtlogo4.png Binary files differnew file mode 100644 index 0000000..7c8aa64 --- /dev/null +++ b/doc/src/images/declarative-qtlogo4.png diff --git a/doc/src/images/declarative-qtlogo5.png b/doc/src/images/declarative-qtlogo5.png Binary files differnew file mode 100644 index 0000000..b7b3513 --- /dev/null +++ b/doc/src/images/declarative-qtlogo5.png diff --git a/doc/src/images/declarative-qtlogo6.png b/doc/src/images/declarative-qtlogo6.png Binary files differnew file mode 100644 index 0000000..07a078f --- /dev/null +++ b/doc/src/images/declarative-qtlogo6.png diff --git a/doc/src/images/declarative-rect.png b/doc/src/images/declarative-rect.png Binary files differnew file mode 100644 index 0000000..173759a --- /dev/null +++ b/doc/src/images/declarative-rect.png diff --git a/doc/src/images/declarative-rect_gradient.png b/doc/src/images/declarative-rect_gradient.png Binary files differnew file mode 100644 index 0000000..f79d579 --- /dev/null +++ b/doc/src/images/declarative-rect_gradient.png diff --git a/doc/src/images/declarative-rect_tint.png b/doc/src/images/declarative-rect_tint.png Binary files differnew file mode 100644 index 0000000..3a44013 --- /dev/null +++ b/doc/src/images/declarative-rect_tint.png diff --git a/doc/src/images/declarative-removebutton-close.png b/doc/src/images/declarative-removebutton-close.png Binary files differnew file mode 100644 index 0000000..d73f8e1 --- /dev/null +++ b/doc/src/images/declarative-removebutton-close.png diff --git a/doc/src/images/declarative-removebutton-open.png b/doc/src/images/declarative-removebutton-open.png Binary files differnew file mode 100644 index 0000000..b54d797 --- /dev/null +++ b/doc/src/images/declarative-removebutton-open.png diff --git a/doc/src/images/declarative-removebutton.gif b/doc/src/images/declarative-removebutton.gif Binary files differnew file mode 100644 index 0000000..ca4d7e6 --- /dev/null +++ b/doc/src/images/declarative-removebutton.gif diff --git a/doc/src/images/declarative-removebutton.png b/doc/src/images/declarative-removebutton.png Binary files differnew file mode 100644 index 0000000..f783e6a --- /dev/null +++ b/doc/src/images/declarative-removebutton.png diff --git a/doc/src/images/declarative-reuse-1.png b/doc/src/images/declarative-reuse-1.png Binary files differnew file mode 100644 index 0000000..c704457 --- /dev/null +++ b/doc/src/images/declarative-reuse-1.png diff --git a/doc/src/images/declarative-reuse-2.png b/doc/src/images/declarative-reuse-2.png Binary files differnew file mode 100644 index 0000000..0b6006b --- /dev/null +++ b/doc/src/images/declarative-reuse-2.png diff --git a/doc/src/images/declarative-reuse-3.png b/doc/src/images/declarative-reuse-3.png Binary files differnew file mode 100644 index 0000000..695a725 --- /dev/null +++ b/doc/src/images/declarative-reuse-3.png diff --git a/doc/src/images/declarative-reuse-bluerect.png b/doc/src/images/declarative-reuse-bluerect.png Binary files differnew file mode 100644 index 0000000..97dbb5f --- /dev/null +++ b/doc/src/images/declarative-reuse-bluerect.png diff --git a/doc/src/images/declarative-reuse-focus.png b/doc/src/images/declarative-reuse-focus.png Binary files differnew file mode 100644 index 0000000..f91d374 --- /dev/null +++ b/doc/src/images/declarative-reuse-focus.png diff --git a/doc/src/images/declarative-rotation.png b/doc/src/images/declarative-rotation.png Binary files differnew file mode 100644 index 0000000..994011b --- /dev/null +++ b/doc/src/images/declarative-rotation.png diff --git a/doc/src/images/declarative-roundrect.png b/doc/src/images/declarative-roundrect.png Binary files differnew file mode 100644 index 0000000..607da81 --- /dev/null +++ b/doc/src/images/declarative-roundrect.png diff --git a/doc/src/images/declarative-scale.png b/doc/src/images/declarative-scale.png Binary files differnew file mode 100644 index 0000000..bab729e --- /dev/null +++ b/doc/src/images/declarative-scale.png diff --git a/doc/src/images/declarative-scalegrid.png b/doc/src/images/declarative-scalegrid.png Binary files differnew file mode 100644 index 0000000..32d87125 --- /dev/null +++ b/doc/src/images/declarative-scalegrid.png diff --git a/doc/src/images/declarative-text.png b/doc/src/images/declarative-text.png Binary files differnew file mode 100644 index 0000000..c1a4112 --- /dev/null +++ b/doc/src/images/declarative-text.png diff --git a/doc/src/images/declarative-textedit.gif b/doc/src/images/declarative-textedit.gif Binary files differnew file mode 100644 index 0000000..7186eb9 --- /dev/null +++ b/doc/src/images/declarative-textedit.gif diff --git a/doc/src/images/declarative-textformat.png b/doc/src/images/declarative-textformat.png Binary files differnew file mode 100644 index 0000000..ade1b45 --- /dev/null +++ b/doc/src/images/declarative-textformat.png diff --git a/doc/src/images/declarative-textstyle.png b/doc/src/images/declarative-textstyle.png Binary files differnew file mode 100644 index 0000000..858c1bc --- /dev/null +++ b/doc/src/images/declarative-textstyle.png diff --git a/doc/src/images/declarative-transformorigin.png b/doc/src/images/declarative-transformorigin.png Binary files differnew file mode 100644 index 0000000..4af320f --- /dev/null +++ b/doc/src/images/declarative-transformorigin.png diff --git a/doc/src/images/declarative-tutorial-list-closed.png b/doc/src/images/declarative-tutorial-list-closed.png Binary files differnew file mode 100644 index 0000000..4a0fee9 --- /dev/null +++ b/doc/src/images/declarative-tutorial-list-closed.png diff --git a/doc/src/images/declarative-tutorial-list-open.gif b/doc/src/images/declarative-tutorial-list-open.gif Binary files differnew file mode 100644 index 0000000..5b93597 --- /dev/null +++ b/doc/src/images/declarative-tutorial-list-open.gif diff --git a/doc/src/images/declarative-tutorial-list-open.png b/doc/src/images/declarative-tutorial-list-open.png Binary files differnew file mode 100644 index 0000000..16a9c94 --- /dev/null +++ b/doc/src/images/declarative-tutorial-list-open.png diff --git a/doc/src/images/declarative-tutorial-list.gif b/doc/src/images/declarative-tutorial-list.gif Binary files differnew file mode 100644 index 0000000..24db426 --- /dev/null +++ b/doc/src/images/declarative-tutorial-list.gif diff --git a/doc/src/images/declarative-tutorial-list.png b/doc/src/images/declarative-tutorial-list.png Binary files differnew file mode 100644 index 0000000..723fe2f --- /dev/null +++ b/doc/src/images/declarative-tutorial-list.png diff --git a/doc/src/images/declarative-tutorial1.png b/doc/src/images/declarative-tutorial1.png Binary files differnew file mode 100644 index 0000000..ea0000f --- /dev/null +++ b/doc/src/images/declarative-tutorial1.png diff --git a/doc/src/images/declarative-tutorial2.png b/doc/src/images/declarative-tutorial2.png Binary files differnew file mode 100644 index 0000000..0538451 --- /dev/null +++ b/doc/src/images/declarative-tutorial2.png diff --git a/doc/src/images/declarative-tutorial3_animation.gif b/doc/src/images/declarative-tutorial3_animation.gif Binary files differnew file mode 100644 index 0000000..d2d4c63 --- /dev/null +++ b/doc/src/images/declarative-tutorial3_animation.gif diff --git a/doc/src/index.qdoc b/doc/src/index.qdoc index 8b317b1..b11b9b6 100644 --- a/doc/src/index.qdoc +++ b/doc/src/index.qdoc @@ -119,6 +119,7 @@ <li><a href="paintsystem.html">Painting and Printing</a></li> <li><a href="graphicsview.html">Canvas UI with Graphics View</a></li> <li><a href="webintegration.html">Integrating Web Content</a></li> + <li><a href="qtdeclarative.html">Declarative UI</a></li> </ul> </td> <td valign="top" class="largeindex"> diff --git a/doc/src/modules.qdoc b/doc/src/modules.qdoc index 05ff6bc..dede1a2 100644 --- a/doc/src/modules.qdoc +++ b/doc/src/modules.qdoc @@ -65,6 +65,7 @@ \row \o \l{QtWebKit} \o Classes for displaying and editing Web content \row \o \l{QtXml} \o Classes for handling XML \row \o \l{QtXmlPatterns} \o An XQuery & XPath engine for XML and custom data models + \row \o \l{QtDeclarative} \o An engine for declaratively building fluid user interfaces. \row \o \l{Phonon Module}{Phonon} \o Multimedia framework classes \row \o \l{Qt3Support} \o Qt 3 compatibility classes \header \o {2,1} \bold{Modules for working with Qt's tools} diff --git a/doc/src/snippets/declarative/GroupBox.qml b/doc/src/snippets/declarative/GroupBox.qml new file mode 100644 index 0000000..13e7eb6 --- /dev/null +++ b/doc/src/snippets/declarative/GroupBox.qml @@ -0,0 +1,15 @@ +import Qt 4.6 + +ContentWrapper { + id: Container; width: parent.width; height: contents.height + children: [ + Rectangle { + width: parent.width; height: contents.height + color: "white"; pen.width: 2; pen.color: "#adaeb0"; radius: 10 + VerticalLayout { + id: layout; width: parent.width; margin: 5; spacing: 2 + Content { } + } + } + ] +} diff --git a/doc/src/snippets/declarative/comments.qml b/doc/src/snippets/declarative/comments.qml new file mode 100644 index 0000000..806be29 --- /dev/null +++ b/doc/src/snippets/declarative/comments.qml @@ -0,0 +1,11 @@ +import Qt 4.6 + +Text { + text: "Hello world!" //a basic greeting + /* + We want this text to stand out from the rest so + we give it a large size and different font. + */ + font.family: "Helvetica" + font.pointSize: 24 +} diff --git a/doc/src/snippets/declarative/content.qml b/doc/src/snippets/declarative/content.qml new file mode 100644 index 0000000..fb03ced --- /dev/null +++ b/doc/src/snippets/declarative/content.qml @@ -0,0 +1,9 @@ +import Qt 4.6 + +Rectangle { + width: 200; height: 100; color: "lightgray" + GroupBox { + Text { text: "First Item" } + Text { text: "Second Item" } + } +} diff --git a/doc/src/snippets/declarative/drag.qml b/doc/src/snippets/declarative/drag.qml new file mode 100644 index 0000000..8735d0c --- /dev/null +++ b/doc/src/snippets/declarative/drag.qml @@ -0,0 +1,18 @@ +import Qt 4.6 + +//! [0] +Rectangle { + id: blurtest; width: 600; height: 200; color: "white" + Image { + id: pic; source: "qtlogo-64.png"; anchors.verticalCenter: parent.verticalCenter + opacity: (600.0-pic.x) / 600; + MouseRegion { + anchors.fill: parent + drag.target: pic + drag.axis: "XAxis" + drag.minimumX: 0 + drag.maximumX: blurtest.width-pic.width + } + } +} +//! [0] diff --git a/doc/src/snippets/declarative/gradient.qml b/doc/src/snippets/declarative/gradient.qml new file mode 100644 index 0000000..281360e --- /dev/null +++ b/doc/src/snippets/declarative/gradient.qml @@ -0,0 +1,10 @@ +import Qt 4.6 + +Rectangle { + width: 100; height: 100 + gradient: Gradient { + GradientStop { position: 0.0; color: "red" } + GradientStop { position: 0.33; color: "yellow" } + GradientStop { position: 1.0; color: "green" } + } +} diff --git a/doc/src/snippets/declarative/gridview/dummydata/ContactModel.qml b/doc/src/snippets/declarative/gridview/dummydata/ContactModel.qml new file mode 100644 index 0000000..6868385 --- /dev/null +++ b/doc/src/snippets/declarative/gridview/dummydata/ContactModel.qml @@ -0,0 +1,25 @@ +import Qt 4.6 + +ListModel { + id: ContactModel + ListElement { + name: "Bill Smith" + number: "555 3264" + portrait: "pics/portrait.png" + } + ListElement { + name: "Jim Williams" + number: "555 5673" + portrait: "pics/portrait.png" + } + ListElement { + name: "John Brown" + number: "555 8426" + portrait: "pics/portrait.png" + } + ListElement { + name: "Sam Wise" + number: "555 0473" + portrait: "pics/portrait.png" + } +} diff --git a/doc/src/snippets/declarative/gridview/gridview.qml b/doc/src/snippets/declarative/gridview/gridview.qml new file mode 100644 index 0000000..d0f0623 --- /dev/null +++ b/doc/src/snippets/declarative/gridview/gridview.qml @@ -0,0 +1,47 @@ +import Qt 4.6 + +//! [3] +Rectangle { + width: 240; height: 180; color: "white" + // ContactModel model is defined in dummydata/ContactModel.qml + // The viewer automatically loads files in dummydata/* to assist + // development without a real data source. + + // Define a delegate component. A component will be + // instantiated for each visible item in the list. +//! [0] + Component { + id: Delegate + Item { + id: Wrapper + width: 80; height: 78 + VerticalLayout { + Image { source: portrait; anchors.horizontalCenter: parent.horizontalCenter } + Text { text: name; anchors.horizontalCenter: parent.horizontalCenter } + } + } + } +//! [0] + // Define a highlight component. Just one of these will be instantiated + // by each ListView and placed behind the current item. +//! [1] + Component { + id: Highlight + Rectangle { + color: "lightsteelblue" + radius: 5 + } + } +//! [1] + // The actual grid +//! [2] + GridView { + width: parent.width; height: parent.height + model: ContactModel; delegate: Delegate + cellWidth: 80; cellHeight: 80 + highlight: Highlight + focus: true + } +//! [2] +} +//! [3] diff --git a/doc/src/snippets/declarative/gridview/pics/portrait.png b/doc/src/snippets/declarative/gridview/pics/portrait.png Binary files differnew file mode 100644 index 0000000..fb5052a --- /dev/null +++ b/doc/src/snippets/declarative/gridview/pics/portrait.png diff --git a/doc/src/snippets/declarative/listview/dummydata/ContactModel.qml b/doc/src/snippets/declarative/listview/dummydata/ContactModel.qml new file mode 100644 index 0000000..31e02ea --- /dev/null +++ b/doc/src/snippets/declarative/listview/dummydata/ContactModel.qml @@ -0,0 +1,17 @@ +import Qt 4.6 + +ListModel { + id: ContactModel + ListElement { + name: "Bill Smith" + number: "555 3264" + } + ListElement { + name: "John Brown" + number: "555 8426" + } + ListElement { + name: "Sam Wise" + number: "555 0473" + } +} diff --git a/doc/src/snippets/declarative/listview/highlight.qml b/doc/src/snippets/declarative/listview/highlight.qml new file mode 100644 index 0000000..29f41bf --- /dev/null +++ b/doc/src/snippets/declarative/listview/highlight.qml @@ -0,0 +1,51 @@ +import Qt 4.6 + +Rectangle { + width: 180; height: 200; color: "white" + + // ContactModel model is defined in dummydata/ContactModel.qml + // The viewer automatically loads files in dummydata/* to assist + // development without a real data source. + + // Define a delegate component. A component will be + // instantiated for each visible item in the list. +//! [0] + Component { + id: Delegate + Item { + id: Wrapper + width: 180; height: 40 + VerticalLayout { + x: 5; y: 5 + Text { text: '<b>Name:</b> ' + name } + Text { text: '<b>Number:</b> ' + number } + } + } + } +//! [0] + // Specify a highlight with custom movement. Note that autoHighlight + // is set to false in the ListView so that we can control how the + // highlight moves to the current item. +//! [1] + Component { + id: Highlight + Rectangle { + width: 180; height: 40 + color: "lightsteelblue"; radius: 5 + y: Follow { + source: List.current.y + spring: 3 + damping: 0.1 + } + } + } + ListView { + id: List + width: parent.height; height: parent.height + model: ContactModel; delegate: Delegate + highlight: Highlight + autoHighlight: false + focus: true + } +//! [1] +} diff --git a/doc/src/snippets/declarative/listview/listview.qml b/doc/src/snippets/declarative/listview/listview.qml new file mode 100644 index 0000000..c907077 --- /dev/null +++ b/doc/src/snippets/declarative/listview/listview.qml @@ -0,0 +1,49 @@ +import Qt 4.6 + +//! [3] +Rectangle { + width: 180; height: 200; color: "white" + + // ContactModel model is defined in dummydata/ContactModel.qml + // The viewer automatically loads files in dummydata/* to assist + // development without a real data source. + + // Define a delegate component. A component will be + // instantiated for each visible item in the list. +//! [0] + Component { + id: Delegate + Item { + id: Wrapper + width: 180; height: 40 + VerticalLayout { + x: 5; y: 5 + Text { text: '<b>Name:</b> ' + name } + Text { text: '<b>Number:</b> ' + number } + } + } + } +//! [0] + // Define a highlight component. Just one of these will be instantiated + // by each ListView and placed behind the current item. +//! [1] + Component { + id: Highlight + Rectangle { + color: "lightsteelblue" + radius: 5 + } + } +//! [1] + // The actual list +//! [2] + ListView { + width: parent.width; height: parent.height + model: ContactModel + delegate: Delegate + highlight: Highlight + focus: true + } +//! [2] +} +//! [3] diff --git a/doc/src/snippets/declarative/mouseregion.qml b/doc/src/snippets/declarative/mouseregion.qml new file mode 100644 index 0000000..67857f5 --- /dev/null +++ b/doc/src/snippets/declarative/mouseregion.qml @@ -0,0 +1,26 @@ +import Qt 4.6 + +Rectangle { width: 200; height: 100 +HorizontalLayout { +//! [0] +Rectangle { width: 100; height: 100; color: "green" + MouseRegion { anchors.fill: parent; onClicked: { parent.color = 'red' } } +} +//! [0] +//! [1] +Rectangle { + width: 100; height: 100; color: "green" + MouseRegion { + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.RightButton + onClicked: { + if (mouse.button == Qt.RightButton) + parent.color = 'blue'; + else + parent.color = 'red'; + } + } +} +//! [1] +} +} diff --git a/doc/src/snippets/declarative/pathview/dummydata/MenuModel.qml b/doc/src/snippets/declarative/pathview/dummydata/MenuModel.qml new file mode 100644 index 0000000..20b3b7d --- /dev/null +++ b/doc/src/snippets/declarative/pathview/dummydata/MenuModel.qml @@ -0,0 +1,17 @@ +import Qt 4.6 + +ListModel { + id: MenuModel + ListElement { + name: "Bill Jones" + icon: "pics/qtlogo-64.png" + } + ListElement { + name: "Jane Doe" + icon: "pics/qtlogo-64.png" + } + ListElement { + name: "John Smith" + icon: "pics/qtlogo-64.png" + } +} diff --git a/doc/src/snippets/declarative/pathview/pathattributes.qml b/doc/src/snippets/declarative/pathview/pathattributes.qml new file mode 100644 index 0000000..92d6966 --- /dev/null +++ b/doc/src/snippets/declarative/pathview/pathattributes.qml @@ -0,0 +1,36 @@ +import Qt 4.6 + +Rectangle { + width: 240; height: 200; color: 'white' +//! [0] +//! [1] + Component { + id: Delegate + Item { + id: Wrapper + width: 80; height: 80 + scale: PathView.scale + opacity: PathView.opacity + VerticalLayout { + Image { anchors.horizontalCenter: Name.horizontalCenter; width: 64; height: 64; source: icon } + Text { id: Name; text: name; font.pointSize: 16} + } + } + } +//! [1] +//! [2] + PathView { + anchors.fill: parent; model: MenuModel; delegate: Delegate + path: Path { + startX: 120; startY: 100 + PathAttribute { name: "scale"; value: 1.0 } + PathAttribute { name: "opacity"; value: 1.0 } + PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 } + PathAttribute { name: "scale"; value: 0.3 } + PathAttribute { name: "opacity"; value: 0.5 } + PathQuad { x: 120; y: 100; controlX: -20; controlY: 75 } + } + } +//! [2] +//! [0] +} diff --git a/doc/src/snippets/declarative/pathview/pathview.qml b/doc/src/snippets/declarative/pathview/pathview.qml new file mode 100644 index 0000000..004a1d2 --- /dev/null +++ b/doc/src/snippets/declarative/pathview/pathview.qml @@ -0,0 +1,30 @@ +import Qt 4.6 + +Rectangle { + width: 240; height: 200; color: 'white' +//! [0] +//! [1] + Component { + id: Delegate + Item { + id: Wrapper + width: 80; height: 80 + VerticalLayout { + Image { anchors.horizontalCenter: Name.horizontalCenter; width: 64; height: 64; source: icon } + Text { id: Name; text: name; font.pointSize: 16} + } + } + } +//! [1] +//! [2] + PathView { + anchors.fill: parent; model: MenuModel; delegate: Delegate + path: Path { + startX: 120; startY: 100 + PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 } + PathQuad { x: 120; y: 100; controlX: -20; controlY: 75 } + } + } +//! [2] +//! [0] +} diff --git a/doc/src/snippets/declarative/pathview/pics/qtlogo-64.png b/doc/src/snippets/declarative/pathview/pics/qtlogo-64.png Binary files differnew file mode 100644 index 0000000..4f68e16 --- /dev/null +++ b/doc/src/snippets/declarative/pathview/pics/qtlogo-64.png diff --git a/doc/src/snippets/declarative/pics/qt.png b/doc/src/snippets/declarative/pics/qt.png Binary files differnew file mode 100644 index 0000000..cbed1a9 --- /dev/null +++ b/doc/src/snippets/declarative/pics/qt.png diff --git a/doc/src/snippets/declarative/repeater.qml b/doc/src/snippets/declarative/repeater.qml new file mode 100644 index 0000000..309fead --- /dev/null +++ b/doc/src/snippets/declarative/repeater.qml @@ -0,0 +1,14 @@ +import Qt 4.6 + +//! [0] +Rectangle { width: 220; height: 20; color: "white" + Component { id: Dot + Rectangle { width: 20; height: 20; radius: 10; color: "green" } + } + HorizontalLayout { + Rectangle { width: 10; height: 20; color: "red" } + Repeater { component: Dot; dataSource: 10 } + Rectangle { width: 10; height: 20; color: "blue" } + } +} +//! [0] diff --git a/doc/src/snippets/declarative/rotation.qml b/doc/src/snippets/declarative/rotation.qml new file mode 100644 index 0000000..aaaebee --- /dev/null +++ b/doc/src/snippets/declarative/rotation.qml @@ -0,0 +1,29 @@ +import Qt 4.6 + +Rectangle { + width: 360; height: 80 + color: "white" +//! [0] + HorizontalLayout { + margin: 10 + spacing: 10 + Image { source: "pics/qt.png" } + Image { + source: "pics/qt.png" + transform: Rotation { origin.x: 30; axis.y: 60; axis.z: 0 angle: 18 } + } + Image { + source: "pics/qt.png" + transform: Rotation { origin.x: 30; axis.y: 60; axis.z: 0 angle: 36 } + } + Image { + source: "pics/qt.png" + transform: Rotation { origin.x: 30; axis.y: 60; axis.z: 0; angle: 54 } + } + Image { + source: "pics/qt.png" + transform: Rotation { origin.x: 30; axis.y: 60; axis.z: 0; angle: 72 } + } + } +//! [0] +} diff --git a/doc/src/tutorials/declarative.qdoc b/doc/src/tutorials/declarative.qdoc new file mode 100644 index 0000000..7780988 --- /dev/null +++ b/doc/src/tutorials/declarative.qdoc @@ -0,0 +1,674 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page tutorials-declarative-contacts.html + \startpage {index.html}{Qt Reference Documentation} + \nextpage {tutorials/declarative/contacts/part1}{Chapter 1} + + \title Declarative UI Tutorial + \ingroup howto + \ingroup tutorials + \brief An introduction to using Qt Declarative UI to put together a + simple animated application. + + \omit + At the time of writing the tutorial Declarative UI was still under + development. It is extremely likely that an update will be required + prior to 4.6 release. + \endomit + + This tutorial gives an introduction to using the Qt Declarative UI + animation framework. + + In this process we will learn about some of the basics of using + Declarative UI, such as + + \list + \o Basic drawing + \o States and Transitions + \o Reuse of components + \o Models and Views + \endlist + + An existing knowledge of Qt is not required. + + The tutorial's source code is located in Qt's + \c examples/declarative/tutorials/contacts directory. + It is split up into a number of sub directories, and within each + sub directory the files are numbered in an order of increasing features. + + The code in this example is not compiled, but interpreted at run time. + This means you should use the qmlviewer application provided with + Qt to run the examples. + + \list + \o \l{tutorials/declarative/contacts/part1}{Drawing and Animation} + \o \l{tutorials/declarative/contacts/part2}{Reusing QML Components} + \o \l{tutorials/declarative/contacts/part3}{Models, Views and Delegates} + \endlist +*/ + +/*! + \page tutorials-declarative-contacts-part1.html + \contentspage {Declarative UI Tutorial}{Contents} + \nextpage {tutorials/declarative/contacts/part2}{Chapter 2} + \example tutorials/declarative/contacts/part1 + \title Drawing and Animation + \tableofcontents + + The first part of this tutorial covers basic drawing of elements on the + screen and causing them to animate. + + \section1 Drawing + + In this first chapter we will build a button that indicates something + can be removed and asks for confirmation. When clicked it will expand + from a small button with a trash can icon, to a wide button with a + confirm icon on the left, the text "Remove" in the middle, and a + cancel icon on the right. + + \image declarative-removebutton.gif + + Because Declarative UI is declarative, you don't pass instructions on + what to paint in a sequential manner as you may be used to. Instead + elements and how they appear on the screen are declared in much the + same was as elements on a web page are declared. This is done using + the Qt Markup Language which we will refer to by the abbreviation QML + for the remainder of the tutorial. + + We will start by drawing a simple red rectangle with rounded corners. + + \image declarative-roundrect.png + + \snippet declarative/tutorials/contacts/1_Drawing_and_Animation/1/RemoveButton.qml 0 + + This is one of the simplest of QML components. It describes a rectangle with + some simple properties. In QML all components start with a capital + letter, and their properties with lower case letters. + + Apart from the properties all QML components share, the \l{Rectangle}{Rectangle} component has the properties + + \list + \o color - The background color of the rectangle + \o tintColor - The overlay color of the rectangle + \o gradientColor - The color at the base of the rectangle to blend upwards + \o pen - The description of how to draw the border of the rectangle + \o radius - The corner radius used to draw rounded rectangles. + \endlist + + There are also a number of properties all QML components shares, described + in the \l{Item}{Item} element reference documentation. The rectangle drawn in the + above code uses the properties; + + \list + \o id - An identifier of the component + \o width - the width of the component when drawn + \o height - the height of the component when drawn + \endlist + + Currently we have described a rectangle with a width and height of 30 pixels, filled in with + the color red and with rounded corners using a radius of 5. + + \section1 Layout + + The next step of the tutorial adds an image over the rectangle. We + will do this by adding an \l{Image}{Image} component as a child of the + \l{Rectangle}{Rectangle} component. All QML components have a list of children which + are drawn in order after the parent component has been drawn. + By having the \l{Image}{Image} + component as a child of the \l{Rectangle}{Rectangle} component we ensure it is drawn + over the \l{Rectangle}{Rectangle} component. Children also are affected by the opacity + of the parent component and calculate their position in within the bounds of + the parent component. + + \image declarative-removebutton-close.png + + \snippet declarative/tutorials/contacts/1_Drawing_and_Animation/2/RemoveButton.qml 0 + + The trashIcon image is added as a child of the Rectangle. In this case + the children property isn't explicitly used because the default property + of the \l{Rectangle}{Rectangle} component is its children. Some elements often don't have children + and use some other default component. When this is the case its possible + to explicitly list the sub component as a child as follows: + + \snippet declarative/tutorials/contacts/1_Drawing_and_Animation/2a/RemoveButton.qml 0 + + The \l{Image}{Image} element allows loading an image file for display. The source + specified is a URL, and in this case refers to a portable network graphics + file in a relative directory to where the QML file was loaded from. + + Also new in this code is the use of anchors. In QML components can either + have their position and size specified explicitly using x, y, width + and height, or they can instead specify the size and position in relation + to either parent or sibling elements. The \l{Image}{Image} component uses + a combination of both styles. It has a fixed size, but specifies its + position to align to the right of its parent and for its vertical center + to align with the vertical center of its parent. Setting a property + by the identifier of a separate property binds them. This means + that if while running the example the position of the \l{Rectangle}{Rectangle} component's + vertical center changed, so to would the vertical center of + the \l{Image}{Image} component. + + The parent value is a special identifier that always refers to the + parent component of a component. + + Anchors are most useful when the size of items might change based on + the component state or contents. However they are limited in that they + must always refer to a parent or sibling component. See + \l{anchor-layout}{Anchor-based Layout} for more information on using + anchors in QML. + + At this point the initial state of the RemoveButton is complete. A small + rounded rectangle with a trash icon. Next we will design the open + state for the button. + + \image declarative-removebutton-open.png + + This is a wider rectangle with two images and some text. The code to + draw this state of the button could be written as follows: + + \snippet declarative/tutorials/contacts/1_Drawing_and_Animation/3/RemoveButton.qml 0 + + The rectangle width is now wider by 200 pixels. Also the trashIcon has + been replaced. Normally we wouldn't + remove the trashIcon when developing an alternate state of the RemoveButton, + however since this is a tutorial its been done so that its easier to + understand the alternate state we are aiming for and how it relates to + transitioning between states. + + We also introduce the \l{Text}{Text} element. + Left and Right anchors are specified in terms of the neighboring icons + because we want text to fill the space between the icons. This + means as the parent removeButton gets wider, so will the text component. + It also means that if we animate a width change on the removeButton, + any bindings, that is the values specified by an expression such as + \c{parent.left} will be evaluated and animated as well. + + \section1 Defining States + + When designing a component with multiple states, it should be developed + in the initial state and the changes that would be made specified + as an additional state. Its not normally possible to add new children + to an element when changing state + This means that all possible child components should be included + in the initial state, and those that should not be visible in the initial + state should have their opacity set to zero. Thus + for the RemoveButton we specify the starting size of the RemoveButton + and hide any items that should not initially be visible. + + The code snippet below shows what the start of the duel state specification + might look like. + + \code + Rectangle { + id: removeButton + width: 30 + height: 30 + color: "red" + radius: 5 + Image { + id: trashIcon + width: 22 + height: 22 + anchors.right: parent.right + anchors.rightMargin: 4 + anchors.verticalCenter: parent.verticalCenter + src: "../../shared/pics/trash.png" + opacity: 1 + } + Image { + id: cancelIcon + width: 22 + height: 22 + anchors.right: parent.right + anchors.rightMargin: 4 + anchors.verticalCenter: parent.verticalCenter + src: "../../shared/pics/cancel.png" + opacity: 0 + } + \endcode + + The code above includes components from both states of the RemoveButton, + but by setting opacity="0" for the cancelIcon it means that the + components of the second state won't be drawn yet. + The base state of a component always has an empty name, however new + states can be added that describe how a component and its children + should be changed. For the RemoveButton there is only one non-base state + required. In this tutorial we will name it the 'opened' state. + + \snippet declarative/tutorials/contacts/1_Drawing_and_Animation/4/RemoveButton.qml states + + In the opened state the width of the button itself changes from the base + width of 30 to the new width of 230. Also the opacity of the children + are changed so that the trash icon is now hidden and the other elements + are now visible. + + \section1 Changing States + + To trigger the change we will react to the 'clicked' signal of a + MouseRegion component. + + \snippet declarative/tutorials/contacts/1_Drawing_and_Animation/4/RemoveButton.qml mouse region + + MouseRegion components handle mouse actions within their geometry. This + geometry behaves the same way as painted components, such that children + cover their parents and later siblings will cover earlier siblings and + all the children of the earlier sibling, should they overlap. + + When a component has a signal, such as clicked, the action for the signal + can be specified using \c{onSignalName}, as is done above. In this + case when the clicked signal is emitted by the MouseRegion component, + a function called \c{toggle()} is called. It might also have been written + + \code + onClicked: { removeButton.state='opened' } + \endcode + + However in this case we are using a function because it allows multiple + mouse regions to use the same functionality, and also makes it + easier to specify complex behavior in response to a signal. + + An alternative would be to explicitly state the connection: + + \snippet declarative/tutorials/contacts/1_Drawing_and_Animation/4a/RemoveButton.qml mouse region + + This will connect to the \c{clicked()} signal of the trashMouseRegion component + and execute the associated script. + + The \c{toggle()} function is a new function specified as part of the remove + button element. + + \snippet declarative/tutorials/contacts/1_Drawing_and_Animation/4/RemoveButton.qml script + + Any QML component can have a set of resources specified. One of those + resources is any Script that might be needed. See the + \l{QtScript Module} for more information on how to write + script code in Qt. + + It is possible to refer to identified QML components + within the script. Hence the function for our RemoveButton will check + if the state is already open to determine what the new state should be. + + \section1 Animation + + Currently the RemoveButton is functional, but snaps between our two states. + Fortunately making the transition between states smooth is very simple. + We only need one more bit of code at the end of our removeButton component. + + \snippet declarative/tutorials/contacts/1_Drawing_and_Animation/5/RemoveButton.qml transition + + All QML components have a transitions property. This describes how + properties of items within the component should change. In this case + we specify that if the x, width or opacity of the removeButton or its + children change due to a change in state, that they should take 200ms + to complete their transition. + + \omit + TODO More on types of animation, e.g. ColorAnimation, Behaviors. + \endomit + + In the next chapter we will show how we can use the remove button in + other QML components. +*/ + +/*! + \page tutorials-declarative-contacts-part2.html + \contentspage {Declarative UI Tutorial}{Contents} + \previouspage {tutorials/declarative/contacts/part1}{Chapter 1} + \nextpage {tutorials/declarative/contacts/part3}{Chapter 3} + \example tutorials/declarative/contacts/part2 + \title Reusing QML Components + \tableofcontents + + The second part of this tutorial covers how to reuse QML components and + have them interact with each other. The RemoveButton developed in the + previous chapter is intended to be part of a more complex control for + editing a field of our contact. This ContactField in turn is intended + to be used in a contact editing control. + + \image declarative-reuse-3.png + + \section1 Loading QML Components + + Reusing the RemoveButton itself is very simple. When parsing a QML file + if a Component is referred to that isn't already in the system, Qt + will try to load it from a file of the same name with the ".qml" extension. + + \snippet declarative/tutorials/contacts/2_Reuse/1/ContactField.qml load + + The above QML code will attempt to load the RemoveButton component from + a file with the name "RemoveButton.qml" from the following search paths. + + \list + \o Any imported directories. These are listed at the start of the file using + \c { import "path" }. + \o the directory of the QML code file + \endlist + + All the properties of the button are + accessible and can be overridden from defaults. The loaded component + can also refer to elements further up in the tree, so that code within + RemoveButton.qml could refer to the contactField component. + Only properties of the top level element in RemoveButton.qml are visible to + the contact field. + + There are also two other ways to reuse components in QML. A component + can be reused from within the same QML file using Component and ComponentInstance + elements. The next code snippet produces three red rounded rectangles + within a large blue rectangle. + + \image declarative-reuse-bluerect.png + + \snippet declarative/tutorials/contacts/2_Reuse/1b/BlueRect.qml all + + This can be useful when the component is not complex enough to justify its + own file. The third way to reuse components allows for delaying loading + of the QML until some later event. \l{Loader}{Loader} includes + a special child, item, which has its definition provided by the + contents of the source property of the loader. + + \snippet declarative/tutorials/contacts/2_Reuse/1a/ContactField.qml load + + This last method is useful if the contents of a item need to change at + run time or if the initial complexity of the loaded QML needs to be + reduced in order to improve the time it takes to start the application. In + chapter three this method is used to improve performance of + scrolling through very large numbers of items. + + Because of its simplicity, the first method is the recommended in most + cases and will be the focus of the remainder of this chapter. + + \section1 Properties and Signals + + The next task is to be able to control aspects of the RemoveButton from + the components that use it. In particular controlling how far it + expands and how it reacts when the user clicks on the confirm icon + of the remove button. When reusing a component in a separate QML file + only the attributes of the root element are visible. To allow controlling + attributes of child elements within an imported component we need to define + some properties and signals for the RemoveButton. + + \snippet declarative/tutorials/contacts/2_Reuse/2/RemoveButton.qml define properties and signals + + The children of the remove button can use these properties and signals. The + opened state can now bind the expanded width to the expandedWidth property. + + \snippet declarative/tutorials/contacts/2_Reuse/2/RemoveButton.qml use width + + Also when the confirm icon is clicked, as well as toggling the state it will + emit the confirmed signal of the RemoveButton component. + + \snippet declarative/tutorials/contacts/2_Reuse/2/RemoveButton.qml use signal + + These properties and signals can also be accessed from the contact field the same + way standard system component properties and signals are accessed. + + \snippet declarative/tutorials/contacts/2_Reuse/2/ContactField.qml use properties and signals + + Now when the remove button is expanded, it will expand to the width of the + contact field. Also when the user confirms the remove action, the + text section of the contact field will be cleared. + + \section1 States + + Its also possible to access the state of included components. The FieldText + component we will use in this tutorial is also been written specifically + for our contacts application. In + this case we want it to expand when editing. One way to do this would + be to anchor the field text component to the center of its parent and + then let its own width change push the remove button away, however that + would make it difficult to have the remove button also push the field + text to the left when the remove button expands. Instead we will anchor + the right edge of the field text to the left edge of the remove button + and use a state change in the contact field itself to move the + remove button and the field icon out of + view. + + \snippet declarative/tutorials/contacts/2_Reuse/3/ContactField.qml all + + Apart from accessing the fieldText.state, the above code also uses the when + attribute of its own editingText state. This is an alternative to using + a signal to change state. When the value of the expression for the + when attribute changes, Qt will detect if the contactField needs to enter + that state. In the FieldText element a similar approach is used to fade + out the label of the FieldText when the user enters some text of their own. + + \snippet declarative/tutorials/contacts/2_Reuse/3/FieldText.qml behavior + + \c{fieldText} is the enclosing component and \c{textEdit} is a TextEdit element + provided by Qt. In the QML code above, the opacity of the textLabel is + only 1 if the text for the textEdit is empty. This is a form of + short cut to using states for an element, useful if only one property + is changing as it is for the textLabel. To animate a property change is + similar to animating a state change. Using the Behavior element we can + specify how the property changes if it does change state, allowing for + a smooth transition. + + \section1 Key and Mouse Focus + + Setting focus to true on a component does not always mean + that the component has focus. This is due to the declarative nature + of QML, and can be affected by multiple components both indicating + focus to be true. At the time of writing this tutorial both key and mouse + focus handling are still being improved. Hence we will only lightly cover + the topic. + + For an item to have key focus in QML it is required that: + + \list + \o If there is a FocusScope ancestor of the component that it has focus as well. + \o That it is the most recent component within the focus realms descendent's + to receive focus + \endlist + + The read-only property activeFocus can be used to determine whether a + component will receive key input. Any un-handled keys will be passed to + the components parent, which in turn will pass keys it doesn't handle up to its + own ancestors. + + Some components such as ListView components are also FocusScope components, as they + handle focus among the child list items. + + At this stage of the tutorial it is sufficient to use the setting of 'focus' + as we only have a list of line edits and only one should be active at any given time. + + Currently if multiple contact fields were put into our contact editor, + any of the FieldText components could be clicked and opened, and + any of the RemoveButton components could be clicked and opened, all + at the same time. This leads to situations where the users actions + are ambiguous + + \image declarative-reuse-focus.png + + To counteract this we will add a property of the root element to indicate + when an element has 'grabbed' mouse interaction, preventing other + clickable elements from reacting. + + \snippet declarative/tutorials/contacts/2_Reuse/4/Contact.qml grab property + + The code that we want to disable then simply needs to check this property before + acting. + + \snippet declarative/tutorials/contacts/2_Reuse/4/RemoveButton.qml grab + + \note Handling Key and Mouse focus in QML is quite likely to change before + the Qt 4.6 release. +*/ + +/*! + \page tutorials-declarative-contacts-part3.html + \contentspage {Declarative UI Tutorial}{Contents} + \previouspage {tutorials/declarative/contacts/part2}{Chapter 2} + \example tutorials/declarative/contacts/part3 + \title Models, Views and Delegates + \tableofcontents + + In the previous chapters we designed a component to display and + edit a contact. The next step is to display a list of those contacts + and allow the user to expand individual contacts for editing. + + As the previous elements will not be changed in this section, they have + been moved to a lib directory for this tutorial and the relevant + import path has been used. + + \section1 Simple List View + + Displaying lists requires three components. A model that holds the + data displayed, a delegate to indicate how elements are drawn and + a view to arrange the elements. + + \image declarative-tutorial-list.gif + + For the purposes of this tutorial we will be using an SQL query as our + data model. This can be declared in the resources section of + the parent item. + + \snippet declarative/tutorials/contacts/3_Collections/1/ContactView.qml model + + The SqlConnection component describes how to connect to the database in + much the same ways as the QSqlDatabase::addDatabase() function is used. + In this case an SQLite database is used as it can be connected to as a + file, reducing complexity in setting up a database server or credentials. + + The SqlQuery component allows various forms of queries to be described. + When the query is a select statement, the component also acts as a model + allowing it to provide data to a ListView component. The query above + retrieves the fields recid, label, email and phone from a contacts table, + and orders the results by the label of the contact first, and then by + the recid for any contacts with equivalent labels. + + The ListView component is suitable for displaying models and is declared + much like any other QML component. The ListView component also has + a delegate property that defines how to construct components for items in the list. + + \snippet declarative/tutorials/contacts/3_Collections/1/ContactView.qml delegate + + Unlike a child element, this describes a template on how to build the component + for each element, much in the same way that components are loaded from + files such as RemoveButton.qml. The are constructed or destroyed as items + scroll into our out of the visible area of the list. + + The entire view component will look like: + + \snippet declarative/tutorials/contacts/3_Collections/1/ContactView.qml view + + This gives us a list of contacts that the user can flick through. + + \section1 Animating Delegates + + The next step is to allow the user to click on a contact to edit the + contact. We will take advantage of QML to open a Contact component + in the list rather than as a new dialog or view. This is very + similar to how the contents of the FieldText and RemoveButton components + are swapped in and out. + + \image declarative-tutorial-list-open.gif + + \snippet declarative/tutorials/contacts/3_Collections/2/ContactView.qml components + + The first step is to have two children of our delegate component that can + be swapped between. The plain Text component and the Contact component built + in the previous chapters. We also add a MouseRegion that can be clicked upon + to change the state of the delegate component. + + \snippet declarative/tutorials/contacts/3_Collections/2/ContactView.qml states + + This defines the open state of the delegate. It changes the height of the delegate + component to that of the whole list view, pushing the other items off each end of + the list. It sets the listview's scroll viewportY of the ListView to the + y value of the delegate so that the top of the delegate matches the top of the list view. + The next step is to lock the list view. This prevents the user being able to flick + the list view. The final to properties that are set should + be familiar from previous chapters, setting the opacity of the items such + that the new item is visible and the old item hidden. + + We then add a transition so that this becomes animated: + + \snippet declarative/tutorials/contacts/3_Collections/2/ContactView.qml transitions + + This allows the user to click on an item to enter the open state. Elsewhere on our + contact view we add a button so that the user can leave the detailed view of the contact. + + \snippet declarative/tutorials/contacts/3_Collections/2/ContactView.qml button + + And connect it's clicked value to some script to set the state of the delegate + back to its default state. + + \snippet declarative/tutorials/contacts/3_Collections/2/ContactView.qml connections + + Something worth noting at this point is that every delegate created has this connection. + It is important to check whether the delegate is the one in the open state, and + taking some effort to ensure only one is, before acting on the signal from the button. + + \section1 Performance Considerations + + We have now made a contact application that can view a list of contacts, open one, + and close it again. Its now time to take a moment and consider the implications + of a list view delegate. It is created for each and every item in the list, + and while the list cleans up after itself and only has delegate components constructed + for visible items and any single point of animation, the list can scroll very quickly. + This means potentially thousands of delegate components will be constructed and + destroyed when the user is flicking through the list. + + Its important then to try and minimize the complexity of the delegate. This + can be done by delaying the loading of the component. By using the qml property + of the \l{Item}{Item} component, we can delay building the Contact.qml item until the user + attempts to open the list. + + \snippet declarative/tutorials/contacts/3_Collections/3/ContactView.qml setting qml + + \l{Loader}{Loader} has a source property that represents the filename for the contents of + a special item child of the \l{Loader}{Loader}. By setting the source property of the Details + component on clicking the mouse region, the more complex component isn't loaded + until needed. The down side about this though is the properties of Contact + cannot be set until the item is loaded. This requires using the Bind element. + + + \snippet declarative/tutorials/contacts/3_Collections/3/ContactView.qml binding + + Unlike binding a value to the property of a component directly, the Bind element + allows both the target and the property set to themselves be to dynamic values. + This means that when the source property is set, it will change the + item property of the Details component. This in turn triggers the Bind + elements to set the required properties of the item, which is now + an instance of the Contact component. +*/ |