diff options
Diffstat (limited to 'doc/src/qml/qmlengine.qdoc')
-rw-r--r-- | doc/src/qml/qmlengine.qdoc | 477 |
1 files changed, 477 insertions, 0 deletions
diff --git a/doc/src/qml/qmlengine.qdoc b/doc/src/qml/qmlengine.qdoc new file mode 100644 index 0000000000..3e8ef1ae3f --- /dev/null +++ b/doc/src/qml/qmlengine.qdoc @@ -0,0 +1,477 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! +\target qmlengine +\page qmlengine.html +\ingroup qml-features +\title The QML Engine +\brief the engine runs QML applications + +The QML engine runs and executes QML +applications. The engine loads, instantiates, and executes the QML context as +specified in QML files, plugins, or applications. + +\section1 Core Module Classes + + The \l{QtDeclarative}{Qt Declarative} module provides a set of C++ APIs for + extending your QML applications from C++ and embedding QML into C++ + applications. There are several core classes in the Qt Declarative module + that provide the essential capabilities for doing this. These are: + + \list + \o QDeclarativeEngine: A QML engine provides the environment for executing QML code. Every + application requires at least one engine instance. + \o QDeclarativeComponent: A component encapsulates QML information. + \o QDeclarativeContext: A context allows an application to expose data to + the QML components created by an engine. + \endlist + + The Qt Declarative module consists of the engine, + context, component encapsulation, and visual items. + + \list + \o QQuickItem + \o QQuickPaintedItem + \o QQuickView + \endlist + + \section2 Declarative Engine + A QDeclarativeEngine allows the configuration of global settings that + apply to all of its QML component instances: for example, the + QNetworkAccessManager to be used for network communications, and the + file path to be used for persistent storage. + + QDeclarativeComponent is used to load QML documents. Each + QDeclarativeComponent instance represents a single document. A component + can be created from the URL or file path of a QML document, or the raw + QML code of the document. Component instances are instatiated through + the QDeclarativeComponent::create() method, like this: + + \code + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, QUrl::fromLocalFile("MyRectangle.qml")); + QObject *rectangleInstance = component.create(); + + // ... + delete rectangleInstance; + \endcode + + QML documents can also be loaded using QDeclarativeView. This class + provides a convenient QWidget-based view for embedding QML components + into QGraphicsView-based applications. (For other methods of integrating + QML into QWidget-based applications, see \l {Integrating QML Code with + existing Qt UI code}.) + +\section1 Engine and Context Initialization + + \section2 Loading QML Components from C++ + + A QML document can be loaded with QDeclarativeComponent or QDeclarativeView. + QDeclarativeComponent loads a QML component as a C++ object; + QDeclarativeView also does this, but additionally loads the QML component + directly into a QGraphicsView. It is convenient for loading a displayable + QML component into a QWidget-based application. + + For example, suppose there is a \c MyItem.qml file that looks like this: + + \snippet doc/src/snippets/declarative/qtbinding/loading/MyItem.qml start + \snippet doc/src/snippets/declarative/qtbinding/loading/MyItem.qml end + + This QML document can be loaded with QDeclarativeComponent or + QDeclarativeView with the following C++ code. Using a QDeclarativeComponent + requires calling QDeclarativeComponent::create() to create a new instance of + the component, while a QDeclarativeView automatically creates an instance of + the component, which is accessible via QDeclarativeView::rootObject(): + + \table + \row + \o + \snippet doc/src/snippets/declarative/qtbinding/loading/main.cpp QDeclarativeComponent-a + \dots 0 + \snippet doc/src/snippets/declarative/qtbinding/loading/main.cpp QDeclarativeComponent-b + \o + \snippet doc/src/snippets/declarative/qtbinding/loading/main.cpp QDeclarativeView + \endtable + + This \c object is the instance of the \c MyItem.qml component that has been + created. You can now modify the item's properties using + QObject::setProperty() or QDeclarativeProperty: + + \snippet doc/src/snippets/declarative/qtbinding/loading/main.cpp properties + + Alternatively, you can cast the object to its actual type and call functions + with compile-time safety. In this case the base object of \c MyItem.qml is + an \l Item, which is defined by the QDeclarativeItem class: + + \snippet doc/src/snippets/declarative/qtbinding/loading/main.cpp cast + + You can also connect to any signals or call functions defined in the + component using QMetaObject::invokeMethod() and QObject::connect(). See \l + {Exchanging data between QML and C++} below for further details. + + \section3 Locating child objects + + QML components are essentially object trees with children that have siblings + and their own children. Child objects of QML components can be located using + the QObject::objectName property with QObject::findChild(). For example, if + the root item in \c MyItem.qml had a child \l Rectangle item: + + \snippet doc/src/snippets/declarative/qtbinding/loading/MyItem.qml start + \codeline + \snippet doc/src/snippets/declarative/qtbinding/loading/MyItem.qml child + \snippet doc/src/snippets/declarative/qtbinding/loading/MyItem.qml end + + The child could be located like this: + + \snippet doc/src/snippets/declarative/qtbinding/loading/main.cpp findChild + + If \c objectName is used inside a delegate of a ListView, \l Repeater or + some other element that creates multiple instances of its delegates, there + will be multiple children with the same \c objectName. In this case, + QObject::findChildren() can be used to find all children with a matching \c + objectName. + + \warning While it is possible to use C++ to access and manipulate QML + objects deep into the object tree, we recommend that you do not take this + approach outside of application testing and prototyping. One strength of QML + and C++ integration is the ability to implement the QML user interface + separately from the C++ logic and dataset backend, and this strategy breaks + if the C++ side reaches deep into the QML components to manipulate them + directly. This would make it difficult to, for example, swap a QML view + component for another view, if the new component was missing a required \c + objectName. It is better for the C++ implementation to know as little as + possible about the QML user interface implementation and the composition of + the QML object tree. + + + \section2 Embedding C++ Objects into QML Components + + When loading a QML scene into a C++ application, it can be useful to + directly embed C++ data into the QML object. QDeclarativeContext enables + this by exposing data to the context of a QML component, allowing data to be + injected from C++ into QML. + + For example, here is a QML item that refers to a \c currentDateTime value + that does not exist in the current scope: + + \snippet doc/src/snippets/declarative/qtbinding/context/MyItem.qml 0 + + This \c currentDateTime value can be set directly by the C++ application + that loads the QML component, using + QDeclarativeContext::setContextProperty(): + + \snippet doc/src/snippets/declarative/qtbinding/context/main.cpp 0 + + Context properties can hold either QVariant or QObject* values. This means + custom C++ objects can also be injected using this approach, and these + objects can be modified and read directly in QML. Here, we modify the above + example to embed a QObject instance instead of a QDateTime value, and the + QML code invokes a method on the object instance: + + \table + \row + \o + \snippet doc/src/snippets/declarative/qtbinding/context-advanced/applicationdata.h 0 + \codeline + \snippet doc/src/snippets/declarative/qtbinding/context-advanced/main.cpp 0 + \o + \snippet doc/src/snippets/declarative/qtbinding/context-advanced/MyItem.qml 0 + \endtable + + (Note that date/time values returned from C++ to QML can be formatted through + \l{QML:Qt::formatDateTime}{Qt.formatDateTime()} and associated functions.) + + If the QML item needs to receive signals from the context property, it can + connect to them using the \l Connections element. For example, if \c + ApplicationData has a signal named \c dataChanged(), this signal can be + connected to using an \c onDataChanged handler within a \l Connections + object: + + \snippet doc/src/snippets/declarative/qtbinding/context-advanced/connections.qml 0 + + Context properties can be useful for using C++ based data models in a QML view. See the + \l {declarative/modelviews/stringlistmodel}{String ListModel}, + \l {declarative/modelviews/objectlistmodel}{Object ListModel} and + \l {declarative/modelviews/abstractitemmodel}{AbstractItemModel} models for + respective examples on using QStringListModel, QObjectList-based models and QAbstractItemModel + in QML views. + + Also see the QDeclarativeContext documentation for more information. + + +\section1 Invoking QML Entities through the Engine + + QML and C++ objects can communicate with one another through signals, slots + and property modifications. For a C++ object, any data that is exposed to + Qt's \l{The Meta-Object System}{Meta-Object System} that is, properties, + signals, slots and Q_INVOKABLE methods - become available to QML. On the QML + side, all QML object data is automatically made available to the meta-object + system and can be accessed from C++. + + The \l{Creating QML Types} article covers the topic of exposing Qt functions + and properties to the declarative engine. + + \section2 Calling Functions + + QML functions can be called from C++ and vice-versa. + + All QML functions are exposed to the meta-object system and can be called + using QMetaObject::invokeMethod(). Here is a C++ application that uses this + to call a QML function: + + \table + \row + \o \snippet doc/src/snippets/declarative/qtbinding/functions-qml/MyItem.qml 0 + \o \snippet doc/src/snippets/declarative/qtbinding/functions-qml/main.cpp 0 + \endtable + + Notice the Q_RETURN_ARG() and Q_ARG() arguments for + QMetaObject::invokeMethod() must be specified as QVariant types, as this is + the generic data type used for QML functions and return values. + + To call a C++ function from QML, the function must be either a Qt slot, or a + function marked with the Q_INVOKABLE macro, to be available to QML. In the + following example, the QML code invokes methods on the \c myObject object, + which has been set using QDeclarativeContext::setContextProperty(): + + \table + \row + \o + \snippet doc/src/snippets/declarative/qtbinding/functions-cpp/MyItem.qml 0 + \o + \snippet doc/src/snippets/declarative/qtbinding/functions-cpp/myclass.h 0 + \codeline + \snippet doc/src/snippets/declarative/qtbinding/functions-cpp/main.cpp 0 + \endtable + + QML supports the calling of overloaded C++ functions. If there are multiple + C++ functions with the same name but different arguments, the correct + function will be called according to the number and the types of arguments + that are provided. + + + \section2 Receiving Signals + + All QML signals are automatically available to C++, and can be connected to + using QObject::connect() like any ordinary Qt C++ signal. In return, any C++ + signal can be received by a QML object using \l {Signal Handlers}{signal + handlers}. + + Here is a QML component with a signal named \c qmlSignal. This signal is + connected to a C++ object's slot using QObject::connect(), so that the \c + cppSlot() method is called whenever the \c qmlSignal is emitted: + + \table + \row + \o + \snippet doc/src/snippets/declarative/qtbinding/signals-qml/MyItem.qml 0 + \o + \snippet doc/src/snippets/declarative/qtbinding/signals-qml/myclass.h 0 + \codeline + \snippet doc/src/snippets/declarative/qtbinding/signals-qml/main.cpp 0 + \endtable + + To connect to Qt C++ signals from within QML, use a signal handler with the + \c on<SignalName> syntax. If the C++ object is directly creatable from + within QML (see \l {Defining new QML elements} above) then the signal + handler can be defined within the object declaration. In the following + example, the QML code creates a \c ImageViewer object, and the \c + imageChanged and \c loadingError signals of the C++ object are connected to + through \c onImagedChanged and \c onLoadingError signal handlers in QML: + + \table + \row + \o + + \snippet doc/src/snippets/declarative/qtbinding/signals-cpp/imageviewer.h start + \dots 4 + \snippet doc/src/snippets/declarative/qtbinding/signals-cpp/imageviewer.h end + + \o + \snippet doc/src/snippets/declarative/qtbinding/signals-cpp/standalone.qml 0 + \endtable + + (Note that if a signal has been declared as the NOTIFY signal for a + property, QML allows it to be received with an \c on<Property>Changed + handler even if the signal's name does not follow the \c <Property>Changed + naming convention. In the above example, if the "imageChanged" signal was + named "imageModified" instead, the \c onImageChanged signal handler would + still be called.) + + If, however, the object with the signal is not created from within the QML + code, and the QML item only has a reference to the created object - for + example, if the object was set using + QDeclarativeContext::setContextProperty() - then the \l Connections element + can be used instead to create the signal handler: + + \table + \row + \o \snippet doc/src/snippets/declarative/qtbinding/signals-cpp/main.cpp connections + \o \snippet doc/src/snippets/declarative/qtbinding/signals-cpp/MyItem.qml 0 + \endtable + + C++ signals can use enum values as parameters provided that the enum is + declared in the class that is emitting the signal, and that the enum is + registered using Q_ENUMS. See \l {Using enumerations of a custom type} below + for details. + + + \section2 Modifying Properties + + Any properties declared in a QML object are automatically accessible from + C++. Given a QML item like this: + + \snippet doc/src/snippets/declarative/qtbinding/properties-qml/MyItem.qml 0 + + The value of the \c someNumber property can be set and read using + QDeclarativeProperty, or QObject::setProperty() and QObject::property(): + + \snippet doc/src/snippets/declarative/qtbinding/properties-qml/main.cpp 0 + + You should always use QObject::setProperty(), QDeclarativeProperty or + QMetaProperty::write() to change a QML property value, to ensure the QML + engine is made aware of the property change. For example, say you have a + custom element \c PushButton with a \c buttonText property that internally + reflects the value of a \c m_buttonText member variable. Modifying the + member variable directly like this is not a good idea: + + \badcode + // BAD! + QDeclarativeComponent component(engine, "MyButton.qml"); + PushButton *button = qobject_cast<PushButton*>(component.create()); + button->m_buttonText = "Click me"; + \endcode + Since the value is changed directly, this bypasses Qt's \l{The Meta-Object + System}{meta-object system} and the QML engine is not made aware of the + property change. This means property bindings to \c buttonText would not be + updated, and any \c onButtonTextChanged handlers would not be called. + + \target properties-cpp + + Any \l {The Property System}{Qt properties} - that is, those declared with + the Q_PROPERTY() macro - are accessible from QML. Here is a modified version + of the \l {Embedding C++ objects into QML components}{earlier example} on + this page; here, the \c ApplicationData class has a \c backgroundColor + property. This property can be written to and read from QML: + + \table + \row + \o \snippet doc/src/snippets/declarative/qtbinding/properties-cpp/applicationdata.h 0 + \o \snippet doc/src/snippets/declarative/qtbinding/properties-cpp/MyItem.qml 0 + \endtable + + Notice the \c backgroundColorChanged signal is declared as the NOTIFY signal + for the \c backgroundColor property. If a Qt property does not have an + associated NOTIFY signal, the property cannot be used for \l{Property + Binding in QML}, as the QML engine would not be notified when the value + changes. If you are using custom types in QML, make sure their properties + have NOTIFY signals so that they can be used in property bindings. + + The \l{Creating QML Types} article covers the topic of exposing Qt + properties to the runtime. For more information, the + \l{Tutorial: Writing QML extensions with C++}{Writing QML extensions with C++} + tutorial demonstrates basic usage patterns. + +\section1 Loading QML Plugins + + Additional Qt code is runnable in the engine as a QML plugin. The \l{QML + Plugins} article covers the creation and usage patterns of QML plugins. The + QDeclarativeExtensionPlugin class is an abstract class for writing QML + plugins. The \l {How to Create Qt Plugins} contains more information about + Qt's plugin system. + +\target qml-engine-optimization +\section1 Optimization + + Often, to develop high performance elements it is helpful to know more about + the status of the QML engine. For example, it might be beneficial to delay + initializing some costly data structures until after all the properties have + been set. + + The QML engine defines an interface class called QDeclarativeParserStatus, + which contains a number of virtual methods that are invoked at various + stages during component instantiation. To receive these notifications, an + element implementation inherits QDeclarativeParserStatus and notifies the Qt + meta system using the Q_INTERFACES() macro. + + \code + class Example : public QObject, public QDeclarativeParserStatus + { + Q_OBJECT + Q_INTERFACES(QDeclarativeParserStatus) + public: + virtual void componentComplete() + { + qDebug() << "Woohoo! Now to do my costly initialization"; + } + }; + \endcode + +\section1 Memory Management and QVariant types + + It is a component's responsibility to ensure that it does not access or + return pointers to invalid objects. QML makes the following guarentees: + + \list + \o An object assigned to a QObject (or QObject-derived) pointer property + will be valid at the time of assignment. + + Following assignment, it is the responsibility of the class to subsequently + guard this pointer, either through a class specific method or the generic + QPointer class. + + \o An object assigned to a QVariant will be valid at the time of assignment. + + When assigning an object to a QVariant property, QML will always use a + QMetaType::QObjectStar typed QVariant. It is the responsibility of the class + to guard the pointer. A general rule when writing a class that uses QVariant + properties is to check the type of the QVariant when it is set and if the + type is not handled by your class, reset it to an invalid variant. + + \o An object assigned to a QObject (or QObject-derived) list property will + be valid at the time of assignment. + + Following assignment, it is the responsibility of the class to subsequently + guard this pointer, either through a class specific method or the generic + QPointer class. + \endlist + + Components should assume that any QML assigned object can be deleted at any + time, and respond accordingly. If documented as such an element need not + continue to work in this situation, but it must not crash. + +\section1 JavaScript Runtime + + The runtime implements the \l{ECMA-262}{ECMAScript Language Specification} standard. + The reserved words, conditionals, variables, and object behaviors follow + after the standard. + + The \l{JavaScript Code} article has information about placing JavaScript + code within QML code. + +*/ |