From 9d4489ff403e675aceb29497a557b1bb6dd53e73 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Thu, 15 Apr 2010 13:24:14 +1000 Subject: Improve integration docs and add examples --- doc/src/declarative/integrating.qdoc | 148 ++++++++++++++------- .../integrating/graphicswidgets/bluecircle.h | 58 ++++++++ .../graphicswidgets/graphicswidgets.pro | 13 ++ .../snippets/integrating/graphicswidgets/main.qml | 32 +++++ .../snippets/integrating/graphicswidgets/qmldir | 1 + .../integrating/graphicswidgets/redsquare.h | 57 ++++++++ .../integrating/graphicswidgets/shapesplugin.cpp | 61 +++++++++ .../declarative-integrating-graphicswidgets.png | Bin 0 -> 1061 bytes 8 files changed, 319 insertions(+), 51 deletions(-) create mode 100644 doc/src/declarative/snippets/integrating/graphicswidgets/bluecircle.h create mode 100644 doc/src/declarative/snippets/integrating/graphicswidgets/graphicswidgets.pro create mode 100644 doc/src/declarative/snippets/integrating/graphicswidgets/main.qml create mode 100644 doc/src/declarative/snippets/integrating/graphicswidgets/qmldir create mode 100644 doc/src/declarative/snippets/integrating/graphicswidgets/redsquare.h create mode 100644 doc/src/declarative/snippets/integrating/graphicswidgets/shapesplugin.cpp create mode 100644 doc/src/images/declarative-integrating-graphicswidgets.png diff --git a/doc/src/declarative/integrating.qdoc b/doc/src/declarative/integrating.qdoc index 165a735..d4034fa 100644 --- a/doc/src/declarative/integrating.qdoc +++ b/doc/src/declarative/integrating.qdoc @@ -43,44 +43,56 @@ \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 -add QML to your UI, without having to rewrite it. - -\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 -QDeclarativeView widget, and load the QML file into that. You'll then have a new widget -containing your declarative UI, and you can interact with it through the -QDeclarativeView interface. The one drawback of this approach is that QDeclarativeView is a lot -heavier than a QWidget in terms of memory consumption and initialization speed, -and so having large numbers of them may lead to performance degredation. - -For a smooth transition from a QWidget based UI to a QML based UI, simply -rewrite your widgets in QML one at a time, using the above method. When -all of your widgets are written in QML you can rewrite your main widget in -QML, so as to load the other widgets in QML instead of using QDeclarativeViews. Then -you just load the main QML file on startup. - -Keep in mind that QWidgets were designed for different sorts of UIs than QML -was, and so it is not always a good idea to switch. 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 +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 Adding QML to a QGraphicsView based UI -If you have an existing Graphics View based UI you can create new -items in QML, and use \l{QDeclarativeComponent} 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}. +\section1 Integrating with a QGraphicsView-based UI + +\section2 Adding QML widgets to a QGraphicsScene -Example, for local QML files: +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 = new QGraphicsScene; +QGraphicsScene* scene = myExistingGraphicsScene(); QDeclarativeEngine *engine = new QDeclarativeEngine; -QDeclarativeComponent component(engine, QUrl::fromLocalFile(filename)); +QDeclarativeComponent component(engine, QUrl::fromLocalFile("myqml.qml")); QGraphicsObject *object = qobject_cast(component.create()); scene->addItem(object); @@ -90,26 +102,60 @@ 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); +\o QGraphicsView::setOptimizationFlags(QGraphicsView::DontSavePainterState) +\o QGraphicsView::setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate) +\o QGraphicsScene::setItemIndexMethod(QGraphicsScene::NoIndex) \endlist -\section1 Using existing QGraphicsWidgets in QML -Another way of integrating with a QGraphicsView based UI is to expose your -existing QGraphicsWidgets to QML, and constructing your scene in QML. Note that -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. - -You can make custom C++ types -available in QML using the pair of macros listed in \l{Extending QML in C++}. -While this is normally only useful for -types that were designed for QML use, in conjunction with the -\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 in C++} page for details on exposing your C++ types, -and the \l{GraphicsObjectContainer} documentation for details about using it to wrap QGraphicsWidgets. +\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 , 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. + */ diff --git a/doc/src/declarative/snippets/integrating/graphicswidgets/bluecircle.h b/doc/src/declarative/snippets/integrating/graphicswidgets/bluecircle.h new file mode 100644 index 0000000..028718f --- /dev/null +++ b/doc/src/declarative/snippets/integrating/graphicswidgets/bluecircle.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ +//![0] +#include +#include +#include + +class BlueCircle : public QGraphicsWidget +{ + Q_OBJECT +public: + void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) + { + painter->setPen(QColor(Qt::blue)); + painter->drawEllipse(0, 0, size().width(), size().height()); + } +}; + +QML_DECLARE_TYPE(BlueCircle) +//![0] diff --git a/doc/src/declarative/snippets/integrating/graphicswidgets/graphicswidgets.pro b/doc/src/declarative/snippets/integrating/graphicswidgets/graphicswidgets.pro new file mode 100644 index 0000000..21c8a37 --- /dev/null +++ b/doc/src/declarative/snippets/integrating/graphicswidgets/graphicswidgets.pro @@ -0,0 +1,13 @@ +TEMPLATE = lib +CONFIG += qt plugin +QT += declarative + +HEADERS += redsquare.h \ + bluecircle.h + +SOURCES += shapesplugin.cpp + +DESTDIR = lib +OBJECTS_DIR = tmp +MOC_DIR = tmp + diff --git a/doc/src/declarative/snippets/integrating/graphicswidgets/main.qml b/doc/src/declarative/snippets/integrating/graphicswidgets/main.qml new file mode 100644 index 0000000..ffcf79d --- /dev/null +++ b/doc/src/declarative/snippets/integrating/graphicswidgets/main.qml @@ -0,0 +1,32 @@ +import Qt 4.7 +import Qt.widgets 4.7 + +Rectangle { + width: 200 + height: 200 + + RedSquare { + id: square + width: 80 + height: 80 + } + + BlueCircle { + anchors.left: square.right + width: 80 + height: 80 + } + + QGraphicsWidget { + anchors.top: square.bottom + size.width: 80 + size.height: 80 + layout: QGraphicsLinearLayout { + LayoutItem { + preferredSize: "100x100" + Rectangle { color: "yellow"; anchors.fill: parent } + } + } + } +} + diff --git a/doc/src/declarative/snippets/integrating/graphicswidgets/qmldir b/doc/src/declarative/snippets/integrating/graphicswidgets/qmldir new file mode 100644 index 0000000..f94dad2 --- /dev/null +++ b/doc/src/declarative/snippets/integrating/graphicswidgets/qmldir @@ -0,0 +1 @@ +plugin graphicswidgets lib diff --git a/doc/src/declarative/snippets/integrating/graphicswidgets/redsquare.h b/doc/src/declarative/snippets/integrating/graphicswidgets/redsquare.h new file mode 100644 index 0000000..76e7d11 --- /dev/null +++ b/doc/src/declarative/snippets/integrating/graphicswidgets/redsquare.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ +//![0] +#include +#include +#include + +class RedSquare : public QGraphicsWidget +{ + Q_OBJECT +public: + void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) + { + painter->fillRect(0, 0, size().width(), size().height(), QColor(Qt::red)); + } +}; + +QML_DECLARE_TYPE(RedSquare) +//![0] diff --git a/doc/src/declarative/snippets/integrating/graphicswidgets/shapesplugin.cpp b/doc/src/declarative/snippets/integrating/graphicswidgets/shapesplugin.cpp new file mode 100644 index 0000000..4c18ef3 --- /dev/null +++ b/doc/src/declarative/snippets/integrating/graphicswidgets/shapesplugin.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ +//![0] +#include "redsquare.h" +#include "bluecircle.h" + +#include +#include + +class ShapesPlugin : public QDeclarativeExtensionPlugin +{ + Q_OBJECT +public: + void registerTypes(const char *uri) { + qmlRegisterType(uri, 1, 0, "RedSquare"); + qmlRegisterType(uri, 1, 0, "BlueCircle"); + } +}; + +#include "shapesplugin.moc" + +Q_EXPORT_PLUGIN2(shapesplugin, ShapesPlugin); +//![0] diff --git a/doc/src/images/declarative-integrating-graphicswidgets.png b/doc/src/images/declarative-integrating-graphicswidgets.png new file mode 100644 index 0000000..d57f4b9 Binary files /dev/null and b/doc/src/images/declarative-integrating-graphicswidgets.png differ -- cgit v0.12