summaryrefslogtreecommitdiffstats
path: root/examples/datavisualization/qmloscilloscope/doc/src/qmloscilloscope.qdoc
blob: 9fdcd8d2ed2db05186a60c1f79cddc3d69e6569a (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
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc
** All rights reserved.
** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.
**
** If you have questions regarding the use of this file, please use
** contact form at http://qt.digia.com
**
****************************************************************************/

/*!
    \example qmloscilloscope
    \title Qt Quick 2 Oscilloscope Example
    \ingroup qtdatavisualization_examples
    \brief Example of a hybrid C++ and QML application.

    The Qt Quick 2 oscilloscope example shows how to combine C++ and QML in an application,
    as well as showing data that changes realtime.

    \image qmloscilloscope-example.png

    The interesting thing about this example is combining C++ and QML, so we'll concentrate on
    that and skip explaining the basic functionality - for
    more detailed QML example documentation, see \l{Qt Quick 2 Scatter Example}.

    \section1 Data source in C++

    The item model based proxies are good for simple and/or static graphs, but to achieve
    best performance when displaying data changing in realtime, the basic proxies should be used.
    Those are not supported in QML, as the data items they store are not \l{QObject}s and
    cannot therefore be directly manipulated from QML code.
    To overcome this limitation, we implement a simple \c DataSource class in C++ to populate the
    data proxy of the series.

    The \c DataSource class provides three methods that can be called from QML:

    \snippet ../examples/qmloscilloscope/datasource.h 0

    The first method, \c generateData(), creates a cache of simulated oscilloscope data for us
    to display. The data is cached in a format accepted by QSurfaceDataProxy:

    \snippet ../examples/qmloscilloscope/datasource.cpp 0

    The secod method, \c update(), copies one set of the cached data into another array, which we
    set to the data proxy of the series by calling QSurfaceDataProxy::resetArray().
    We reuse the same array if the array dimensions have not changed to minimize overhead:

    \snippet ../examples/qmloscilloscope/datasource.cpp 1

    \note Even though we are operating on the array pointer we have previously set to the proxy
    we still need to call QSurfaceDataProxy::resetArray() after changing the data in it to prompt
    the graph to render the data.

    The final method, \c selectionLabel(), is used to generate a label string we can show on the
    QML ui. This method utilizes the axis formats to format the label:

    \snippet ../examples/qmloscilloscope/datasource.cpp 2

    To be able to access the \c DataSource methods from QML, we need to expose it. We do this by
    defining a context property in application main:

    \snippet ../examples/qmloscilloscope/main.cpp 0

    \section1 QML

    In the QML codes, we define a Surface3D graph normally and give it a Surface3DSeries:

    \snippet ../examples/qmloscilloscope/qml/qmloscilloscope/main.qml 0

    One interesting detail is that we don't specify a proxy for the Surface3DSeries we attach
    to the graph. This makes the series to utilize the default QSurfaceDataProxy.

    We also specify an empty string for \l{Abstract3DSeries::itemLabelFormat}{itemLabelFormat}, since we want to display
    the selected item information in a \c Text element instead of a label above the selection pointer.
    This is done because the selection pointer moves around a lot as the data changes, which makes
    the regular selection label difficult to read.
    When selection point changes, we update the label text using a helper function
    \c updateSelectionLabel(), which calls one of the methods we defined for our \c DataSource class
    to obtain the label:

    \snippet ../examples/qmloscilloscope/qml/qmloscilloscope/main.qml 1

    We initialize the \c DataSource cache when the graph is complete by calling a helper function
    \c generateData(), which calls the method with the same name on the \c DataSource:

    \snippet ../examples/qmloscilloscope/qml/qmloscilloscope/main.qml 2
    \dots 4
    \snippet ../examples/qmloscilloscope/qml/qmloscilloscope/main.qml 4

    To trigger the updates in data, we define a \c Timer item which calls the \c update() method on the \c
    DataSource at requested intervals. The label update is also triggered on each cycle:

    \snippet ../examples/qmloscilloscope/qml/qmloscilloscope/main.qml 3
*/