summaryrefslogtreecommitdiffstats
path: root/doc/src/declarative/integrating.qdoc
blob: d4034fa62ba24b91da19ccb55067ba67df7cd613 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

/*!
\page qml-integration.html
\title Integrating QML with existing Qt UI code

There are a number of ways to integrate QML into QWidget-based UI applications,
depending on the characteristics of your existing UI code.


\section1 Integrating with a \l{QWidget}-based UI

If you have an existing QWidget-based UI, QML widgets can be integrated into
it using QDeclarativeView. QDeclarativeView is a subclass of QWidget so you
can add it to your user interface like any other QWidget. Use 
QDeclarativeView::setSource() to load a QML file into the view, then add the 
view to your UI:

\code
QDeclarativeView *qmlView = new QDeclarativeView;
qmlView->setSource(QUrl::fromLocalFile("myqml.qml"));

QWidget *widget = myExistingWidget();
QVBoxLayout *layout = new QVBoxLayout(widget);
widget->addWidget(qmlView);
\endcode

The one drawback to this approach is that QDeclarativeView is slower to initialize
and uses more memory than a QWidget, and creating large numbers of QDeclarativeView
objects may lead to performance degradation. If this is the case, it may be 
better to rewrite your widgets in QML, and load the widgets from a main QML widget
instead of using QDeclarativeView.

Keep in mind that QWidgets were designed for a different type of user interface
than QML, so it is not always a good idea to port a QWidget-based application to
QML. QWidgets are a better choice if your UI is comprised of a small number of
complex and static elements, and QML is a better choice if your UI is comprised of a large number
of simple and dynamic elements.


\section1 Integrating with a QGraphicsView-based UI

\section2 Adding QML widgets to a QGraphicsScene

If you have an existing UI based on the \l{The Graphics View Framework}{Graphics View Framework},
you can integrate QML widgets directly into your QGraphicsScene. Use
QDeclarativeComponent to create a QGraphicsObject from a QML file, and
place the graphics object into your scene using \l{QGraphicsScene::addItem()}, or 
reparent it to an item already in the \l{QGraphicsScene}.

For example:

\code
QGraphicsScene* scene = myExistingGraphicsScene();
QDeclarativeEngine *engine = new QDeclarativeEngine;
QDeclarativeComponent component(engine, QUrl::fromLocalFile("myqml.qml"));
QGraphicsObject *object =
    qobject_cast<QGraphicsObject *>(component.create());
scene->addItem(object);
\endcode

The following QGraphicsView options are recommended for optimal performance
of QML UIs:

\list
\o QGraphicsView::setOptimizationFlags(QGraphicsView::DontSavePainterState)
\o QGraphicsView::setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate)
\o QGraphicsScene::setItemIndexMethod(QGraphicsScene::NoIndex)
\endlist

\section2 Loading QGraphicsWidget objects in QML

An alternative approach is to expose your existing QGraphicsWidget objects to 
QML and construct your scene in QML instead. To do this, you need to register
any custom C++ types and create a plugin that registers the custom types
so that they can be used from your QML file.

Here is an example. Suppose you have two classes, \c RedSquare and \c BlueCircle,
that both inherit from QGraphicsWidget. First, you need to register these two types
using the \c QML_DECLARE_TYPE macro from \c <QtDeclarative/qdeclarative.h>, like this:

\c [graphicswidgets/redsquare.h]
\snippet doc/src/declarative/snippets/integrating/graphicswidgets/redsquare.h 0

\c [graphicswidgets/bluecircle.h]
\snippet doc/src/declarative/snippets/integrating/graphicswidgets/bluecircle.h 0

Then, create a plugin by subclassing QDeclarativeExtensionPlugin, and register the
types by calling qmlRegisterType(). Also export the plugin with Q_EXPORT_PLUGIN2.

\c [graphicswidgets/shapesplugin.cpp]
\snippet doc/src/declarative/snippets/integrating/graphicswidgets/shapesplugin.cpp 0

Now write a project file that creates the plugin:

\c [graphicswidgets/graphicswidgets.pro]
\quotefile doc/src/declarative/snippets/integrating/graphicswidgets/graphicswidgets.pro

And add a \c qmldir file that includes the \c graphicswidgets plugin from the \c lib
subdirectory (as defined in the project file):

\c [graphicswidgets/qmldir]
\quotefile doc/src/declarative/snippets/integrating/graphicswidgets/qmldir

Now, we can write a QML file that uses the \c RedSquare and \c BlueCircle widgets.
(As an example, we can also create \c QGraphicsWidget items if we import the \c Qt.widgets
module.)

\c [main.qml]
\quotefile doc/src/declarative/snippets/integrating/graphicswidgets/main.qml

Here is a screenshot of the result:

\image declarative-integrating-graphicswidgets.png 


Note this approach of creating your graphics widgets from QML does not work 
with QGraphicsItem objects that are not QGraphicsWidget-based, since they are not QObjects.

See \l{Extending QML in C++} for further information on using C++ types.

*/