diff options
-rw-r--r-- | doc/src/declarative/declarativeui.qdoc | 1 | ||||
-rw-r--r-- | doc/src/declarative/dynamicobjects.qdoc | 179 | ||||
-rw-r--r-- | doc/src/declarative/ecmascriptblocks.qdoc | 10 | ||||
-rw-r--r-- | doc/src/declarative/globalobject.qdoc | 6 | ||||
-rw-r--r-- | doc/src/declarative/integrating.qdoc | 40 | ||||
-rw-r--r-- | doc/src/declarative/qtbinding.qdoc | 2 | ||||
-rw-r--r-- | src/declarative/graphicsitems/qmlgraphicsgraphicsobjectcontainer.cpp | 35 |
7 files changed, 252 insertions, 21 deletions
diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc index 4d2b09c..ae64361 100644 --- a/doc/src/declarative/declarativeui.qdoc +++ b/doc/src/declarative/declarativeui.qdoc @@ -93,6 +93,7 @@ completely new applications. QML is fully \l {Extending QML}{extensible from C+ \o \l {qmlmodules.html}{Modules} \o \l {qmlfocus.html}{Keyboard Focus} \o \l {Extending types from QML} +\o \l {Dynamic Object Creation} \endlist \section1 Reference: diff --git a/doc/src/declarative/dynamicobjects.qdoc b/doc/src/declarative/dynamicobjects.qdoc new file mode 100644 index 0000000..c8ea981 --- /dev/null +++ b/doc/src/declarative/dynamicobjects.qdoc @@ -0,0 +1,179 @@ +/**************************************************************************** +** +** 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 qmldynamicobjects.html +\title Dynamic Object Creation + +QML has some support for dynamically loading and managing QML objects from +within ECMAscript blocks. It is preferable to use the existing QML elements for +dynamic object management wherever possible; these are \l{Loader}, +\l{Repeater}, \l{ListView}, \l{GridView} and \l{PathView}. It is also possible +to dynamically create and manage objects from C++, and this is preferable for +hybrid QML/C++ applications - see \l{Using QML in C++ Applications}. +Dynamically creating and managing objects from +within ECMAscript blocks is intended for when none of the existing QML elements +fit the needs of your application, and you do not desire for your application +to involve C++ code. + +\section1 Creating Objects Dynamically +There are two ways of creating objects dynamically. You can either create +a component which instantiates items, or create an item from a string of QML. +Creating a component is better for the situation where you have a predefined +item which you want to manage dynamic instances of, and creating an item from +a string of QML is intended for when the QML itself is generated at runtime. + +If you have a component specified in a QML file, you can dynamically load it with +the createComponent function on the \l{QML Global Object}. +This function takes the URL of the QML file as its only argument and returns +a component object which can be used to create and load that QML file. + +You can also create a component by placing your QML inside a Component element. +Referencing that component element by id will be the same as referencing the variable +which you save the result of createComponent into. + +Once you have a component you can use its createObject method to create an instance of +the component. Example QML script is below. Remember that QML files that might be loaded + over the network cannot be expected to be ready immediately. + \code + var component; + var sprite; + function finishCreation(){ + if(component.isReady()){ + sprite = component.createObject(); + if(sprite == 0){ + // Error Handling + }else{ + sprite.parent = page; + sprite.x = 200; + //... + } + }else if(component.isError()){ + // Error Handling + } + } + + component = createComponent("Sprite.qml"); + if(component.isReady()){ + finishCreation(); + }else{ + component.statusChanged.connect(finishCreation); + } + \endcode + + If you are certain the files will be local, you could simplify to + + \code + component = createComponent("Sprite.qml"); + sprite = component.createObject(); + if(sprite == 0){ + // Error Handling + console.log(component.errorsString()); + }else{ + sprite.parent = page; + sprite.x = 200; + //... + } + \endcode + +After creating the item, remember to set its parent to an item within the scene. +Otherwise your dynamically created item will not appear in the scene. When using files with relative paths, the path should +be relative to the file where createComponent is executed. + +If the QML does not exist until runtime, you can create a QML item from +a string of QML using the createQmlObject function, as in the following example: + + \code + newObject = createQmlObject('import Qt 4.6; Rectangle {color: "red"; width: 20; height: 20}', + targetItem, "dynamicSnippet1"); + \endcode +The first argument is the string of QML to create. Just like in a new file, you will need to +import any types you wish to use. For importing files with relative paths, the path should +be relative to the file where the item in the second argument is defined. Remember to set the parent after +creating the item. The second argument is another item in the scene, and the new item is created +in the same QML Context as this item. The third argument is the file path associated with this +item, which is used for error reporting. + +\section1 Maintaining Dynamically Created Objects + +Dynamically created objects may be used the same as other objects, however they +will not have an id in QML. + +A restriction which you need to manage with dynamically created items, +is that the creation context must outlive the +created item. The creation context is the QmlContext in which createComponent +was called, or the context in which the Component element, or the item used as the +second argument to createQmlObject, was specified. If the creation +context is destroyed before the dynamic item is, then bindings in the dynamic item will +fail to work. + +\section1 Deleting Objects Dynamically +You should generally avoid dynamically deleting objects that you did not +dynamically create. In many UIs, it is sufficient to set the opacity to 0 or +to move the item off of the edge of the screen. If you have lots of dynamically +created items however, deleting them when they are no longer used will provide +a worthwhile performance benefit. Note that you should never manually delete +items which were dynamically created by QML Elements such as \l{Loader}. + +To manually delete a QML item, call its destroy method. This method has one +argument, which is an approximate delay in ms and which defaults to zero. This +allows you to wait until the completion of an animation or transition. An example: + +\code + Component{ id:fadesOut + Rectangle{ + id: rect + width: 40; height: 40; + opacity: NumberAnimation{from:1; to:0; duration: 1000;} + Component.onCompleted: rect.destroy(1000); + } + } + function createFadesOut(parentItem) + { + var object = fadesOut.createObject(); + object.parent = parentItem; + } +\endcode +In the above example, the dynamically created rectangle calls destroy as soon as it's created, + but delays long enough for its fade out animation to play. + +*/ + diff --git a/doc/src/declarative/ecmascriptblocks.qdoc b/doc/src/declarative/ecmascriptblocks.qdoc index 411d189..749111f 100644 --- a/doc/src/declarative/ecmascriptblocks.qdoc +++ b/doc/src/declarative/ecmascriptblocks.qdoc @@ -54,6 +54,14 @@ assigned to an object property or given an id. The included ECMAScript is evalu in a scope chain. The \l {QML Scope} documentation covers the specifics of scoping in QML. +A restriction on the ECMAScript used in QML is that you cannot add new members to the +global object. This happens transparently when you try to use a variable without +declaring it, and so declaring local variables is required when using ECMA script in +QML. + +The global object in QML has a variety of helper functions added to it, to aid UI +implementation. See \l{QML Global Object} for further details. + Note that if you are adding a function that should be called by external elements, you do not need the \l Script element. See \l {Extending types from QML#Adding new methods} {Adding new methods} for information about adding slots that can be called externally. @@ -123,7 +131,7 @@ until the script has been retrieved. It is occasionally necessary to run a block of ECMAScript code at application (or component instance) "startup". While it is tempting to just include the startup -script as \e {global code} in an external script file, this can have sever limitations +script as \e {global code} in an external script file, this can have severe limitations as the QML environment may not have been fully established. For example, some objects might not have been created or some \l {Property Binding}s may not have been run. \l {QML Script Restrictions} covers the exact limitations of global script code. diff --git a/doc/src/declarative/globalobject.qdoc b/doc/src/declarative/globalobject.qdoc index 74dbc92..b26f223 100644 --- a/doc/src/declarative/globalobject.qdoc +++ b/doc/src/declarative/globalobject.qdoc @@ -130,10 +130,8 @@ This function returns a hex string of the md5 hash of \c data. \section1 Dynamic Object Creation The following functions on the global object allow you to dynamically create QML -items from files or strings. - -You can also dynamically create objects in a declarative manner, using items -such as ListView, \l Repeater and \l Loader. +items from files or strings. See \l{Dynamic Object Management} for an overview +of their use. \section2 createComponent(url file) This function takes the URL of a QML file as its only argument. It returns diff --git a/doc/src/declarative/integrating.qdoc b/doc/src/declarative/integrating.qdoc index fd3b9f7..d93a6ff 100644 --- a/doc/src/declarative/integrating.qdoc +++ b/doc/src/declarative/integrating.qdoc @@ -43,10 +43,10 @@ \page qml-integration.html \title Integrating QML with existing Qt UI code -If you have existing Qt UI code which does not use QML, you can still -use QML in some ways without having to rewrite your UI. +If you have existing Qt UI code which does not use QML you can still +add QML to your UI, without having to rewrite it. -\section1 Adding QML to a QWidget based UI +\section1 Adding QML to a \l{QWidget} based UI If you have an existing QWidget based UI you can simply write new custom widgets in QML. To integrate them into your application you can create a QmlView widget, and load the QML file into that. You'll then have a new widget @@ -68,10 +68,21 @@ elements, and QML is a better choice if your UI is comprised of a large number of simple and dynamic elements. \section1 Adding QML to a QGraphicsView based UI -If you have an existing QGraphicsView based UI you can create new items in QML, -and use QmlComponent to create QGraphicsObjects from the QML primitives. These -QGraphicsObjects can then be manually placed into your QGraphicsScene just like -any other. +If you have an existing Graphics View based UI you can create new items in QML, +and use \l{QmlComponent} to create \l{QGraphicsObject}s from the QML files. These +\l{QGraphicsObject}s can then be placed into your \l{QGraphicsScene} using \l{QGraphicsScene::addItem} +or by reparenting them to an item already in the \l{QGraphicsScene}. + +Example, for local QML files: + +\code +QGraphicsScene* scene = new QGraphicsScene; +QmlEngine *engine = new QmlEngine; +QmlComponent component(engine, QUrl::fromLocalFile(filename)); +QGraphicsObject *object = + qobject_cast<QGraphicsObject *>(component.create()); +scene->addItem(object); +\endcode \section1 Using existing QGraphicsWidgets in QML Another way of integrating with a QGraphicsView based UI is to expose your @@ -80,11 +91,14 @@ this approach will not work with QGraphicsItems which are not QGraphicsWidgets, and that this approach allows you to integrate new items written in QML without using the above method. -As per the instructions in \l{Extending QML}, you can make custom C++ types -available in QML using a pair of macros. While this is normally only useful for +You can make custom C++ types +available in QML using the pair of macros listed in \l{Extending QML}. +While this is normally only useful for types that were designed for QML use, in conjunction with the -\l{GraphicsObjectContainer} element it works for QGraphicsWidgets which can be -controlled through properties. See the \l{GraphicsObjectContainer} -documentation for details about its use. This way you can write your UI using -QML, without having to rewrite any of your complex existing items. +\l{GraphicsObjectContainer} element QGraphicsWidget subclasses can also be +used effectively (if they were designed, like QGraphicsWidget, to be controllable through Qt's property system). +This way you can write your UI using QML, without having to rewrite your existing items. + +For details on implementing this approach see \l{Extending QML} page for details on exposing your C++ types, +and the \l{GraphicsObjectContainer} documentation for details about using it to wrap QGraphicsWidgets. */ diff --git a/doc/src/declarative/qtbinding.qdoc b/doc/src/declarative/qtbinding.qdoc index 61520f7..68723bf 100644 --- a/doc/src/declarative/qtbinding.qdoc +++ b/doc/src/declarative/qtbinding.qdoc @@ -54,6 +54,8 @@ QML also includes a convenience API, QmlView, for applications that simply want components into a new QGraphicsView. QmlView covers up many of the details discussed below. While QmlView is mainly intended for rapid prototyping it can have uses in production applications. +If you are looking at retrofitting an existing Qt application with QML, +read \l{Integrating QML with existing Qt UI code}. \section1 Basic Usage Every application requires at least one QmlEngine. A QmlEngine allows the configuration of diff --git a/src/declarative/graphicsitems/qmlgraphicsgraphicsobjectcontainer.cpp b/src/declarative/graphicsitems/qmlgraphicsgraphicsobjectcontainer.cpp index fa8aaeb..a5a7935 100644 --- a/src/declarative/graphicsitems/qmlgraphicsgraphicsobjectcontainer.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsgraphicsobjectcontainer.cpp @@ -89,11 +89,40 @@ public: provides a lot of important functionality, including anchors and proper management of child items. GraphicsObjectContainer helps provide these functions to other QGraphicsObjects, so that they can be used unaltered in - a QML scene. + a QML scene. QGraphicsObjects, which are not QmlGraphicsItems, and which are + placed in a QML scene outside of a GraphicsObjectContainer, will not appear + on screen at all. A GraphicsObjectContainer can have one element inside it, and it must be a - QGraphicsObject or subclass. The graphics object inside the - GraphicsObjectContainer can then be used normally. + QGraphicsObject or subclass which has been exposed to the QML engine. + The graphics object inside the GraphicsObjectContainer can then be used + like any other item in QML with the exception of not being reparentable + and not having the standard properties of QML items (such as anchors). + + As the contained object is positioned relative to the container, anchors + affecting the container item will affect the onscreen position of the + contained item. If synchronizedResizing is set to true, then anchors + affecting the container item's size will also affect the contained item's + size. + + Example: + \code + import Qt 4.6 + import MyApp 2.1 as Widgets + Rectangle{ + id: rect + property alias widgetPropertyThree: widget.myThirdProperty; + GraphicsObjectContainer{ + synchronizedResizing: true + anchors.margins: 10 + anchors.fill: parent + Widgets.MyWidget{ + myProperty: "A Value" + myOtherProperty: rect.color + } + } + } + \endcode */ /*! |