summaryrefslogtreecommitdiffstats
path: root/examples/datavisualization/qmloscilloscope
diff options
context:
space:
mode:
Diffstat (limited to 'examples/datavisualization/qmloscilloscope')
-rw-r--r--examples/datavisualization/qmloscilloscope/datasource.cpp166
-rw-r--r--examples/datavisualization/qmloscilloscope/datasource.h54
-rw-r--r--examples/datavisualization/qmloscilloscope/doc/images/qmloscilloscope-example.pngbin0 -> 235720 bytes
-rw-r--r--examples/datavisualization/qmloscilloscope/doc/src/qmloscilloscope.qdoc102
-rw-r--r--examples/datavisualization/qmloscilloscope/main.cpp58
-rw-r--r--examples/datavisualization/qmloscilloscope/qml/qmloscilloscope/NewButton.qml52
-rw-r--r--examples/datavisualization/qmloscilloscope/qml/qmloscilloscope/main.qml289
-rw-r--r--examples/datavisualization/qmloscilloscope/qmloscilloscope.desktop11
-rw-r--r--examples/datavisualization/qmloscilloscope/qmloscilloscope.pro24
-rw-r--r--examples/datavisualization/qmloscilloscope/qmloscilloscope.qrc6
-rw-r--r--examples/datavisualization/qmloscilloscope/qmloscilloscope64.pngbin0 -> 3400 bytes
-rw-r--r--examples/datavisualization/qmloscilloscope/qtquick2applicationviewer/qtquick2applicationviewer.cpp81
-rw-r--r--examples/datavisualization/qmloscilloscope/qtquick2applicationviewer/qtquick2applicationviewer.h33
-rw-r--r--examples/datavisualization/qmloscilloscope/qtquick2applicationviewer/qtquick2applicationviewer.pri180
14 files changed, 1056 insertions, 0 deletions
diff --git a/examples/datavisualization/qmloscilloscope/datasource.cpp b/examples/datavisualization/qmloscilloscope/datasource.cpp
new file mode 100644
index 00000000..83ff0ff9
--- /dev/null
+++ b/examples/datavisualization/qmloscilloscope/datasource.cpp
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** 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
+**
+****************************************************************************/
+
+#include "datasource.h"
+#include <qmath.h>
+
+using namespace QtDataVisualization;
+
+Q_DECLARE_METATYPE(QSurface3DSeries *)
+
+DataSource::DataSource(QObject *parent) :
+ QObject(parent),
+ m_index(-1),
+ m_resetArray(0)
+{
+ qRegisterMetaType<QSurface3DSeries *>();
+}
+
+DataSource::~DataSource()
+{
+ clearData();
+}
+
+//! [0]
+void DataSource::generateData(int cacheCount, int rowCount, int columnCount,
+ float xMin, float xMax, float yMin, float yMax,
+ float zMin, float zMax)
+{
+ if (!cacheCount)
+ return;
+
+ clearData();
+ // Re-create the cache array
+ m_data.resize(cacheCount);
+ for (int i(0); i < cacheCount; i++) {
+ QSurfaceDataArray &array = m_data[i];
+ array.reserve(rowCount);
+ for (int j(0); j < rowCount; j++)
+ array.append(new QSurfaceDataRow(columnCount));
+ }
+
+ float xRange = xMax - xMin;
+ float yRange = yMax - yMin;
+ float zRange = zMax - zMin;
+ int cacheIndexStep = columnCount / cacheCount;
+ float cacheStep = float(cacheIndexStep) * xRange / float(columnCount);
+
+ // Populate caches
+ for (int i(0); i < cacheCount; i++) {
+ QSurfaceDataArray &cache = m_data[i];
+ float cacheXAdjustment = cacheStep * i;
+ float cacheIndexAdjustment = cacheIndexStep * i;
+ for (int j(0); j < rowCount; j++) {
+ QSurfaceDataRow &row = *(cache[j]);
+ float rowMod = (float(j)) / float(rowCount);
+ float yRangeMod = yRange * rowMod;
+ float zRangeMod = zRange * rowMod;
+ float z = zRangeMod + zMin;
+ qreal rowColWaveAngleMul = M_PI * M_PI * rowMod;
+ float rowColWaveMul = yRangeMod * 0.2f;
+ for (int k(0); k < columnCount; k++) {
+ float colMod = (float(k)) / float(columnCount);
+ float xRangeMod = xRange * colMod;
+ float x = xRangeMod + xMin + cacheXAdjustment;
+ float colWave = float(qSin((2.0 * M_PI * colMod) - (1.0 / 2.0 * M_PI)) + 1.0);
+ float y = (colWave * ((float(qSin(rowColWaveAngleMul * colMod) + 1.0))))
+ * rowColWaveMul
+ + (0.15f * float(rand()) / float(RAND_MAX)) * yRangeMod;
+
+ int index = k + cacheIndexAdjustment;
+ if (index >= columnCount) {
+ // Wrap over
+ index -= columnCount;
+ x -= xRange;
+ }
+ row[index] = QVector3D(x, y, z);
+ }
+ }
+ }
+}
+//! [0]
+
+//! [1]
+void DataSource::update(QSurface3DSeries *series)
+{
+ if (series && m_data.size()) {
+ // Each iteration uses data from a different cached array
+ m_index++;
+ if (m_index > m_data.count() - 1)
+ m_index = 0;
+
+ QSurfaceDataArray array = m_data.at(m_index);
+ int newRowCount = array.size();
+ int newColumnCount = array.at(0)->size();
+
+ // If the first time or the dimensions of the cache array have changed,
+ // reconstruct the reset array
+ if (m_resetArray || series->dataProxy()->rowCount() != newRowCount
+ || series->dataProxy()->columnCount() != newColumnCount) {
+ m_resetArray = new QSurfaceDataArray();
+ m_resetArray->reserve(newRowCount);
+ for (int i(0); i < newRowCount; i++)
+ m_resetArray->append(new QSurfaceDataRow(newColumnCount));
+ }
+
+ // Copy items from our cache to the reset array
+ for (int i(0); i < newRowCount; i++) {
+ const QSurfaceDataRow &sourceRow = *(array.at(i));
+ QSurfaceDataRow &row = *(*m_resetArray)[i];
+ for (int j(0); j < newColumnCount; j++)
+ row[j].setPosition(sourceRow.at(j).position());
+ }
+
+ // Notify the proxy that data has changed
+ series->dataProxy()->resetArray(m_resetArray);
+ }
+}
+//! [1]
+
+//! [2]
+QString DataSource::selectionLabel(QSurface3DSeries *series, QValue3DAxis *axisX,
+ QValue3DAxis *axisY, QValue3DAxis *axisZ)
+{
+ QString label;
+
+ if (series && series->selectedPoint() != QSurface3DSeries::invalidSelectionPosition()) {
+ const QSurfaceDataItem *item = series->dataProxy()->itemAt(series->selectedPoint());
+ QString x;
+ QString y;
+ QString z;
+ x.sprintf(axisX->labelFormat().toUtf8().constData(), int(item->x()));
+ y.sprintf(axisY->labelFormat().toUtf8().constData(), int(item->y()));
+ z.sprintf(axisZ->labelFormat().toUtf8().constData(), int(item->z()));
+ label = QStringLiteral("%1, %3: %2").arg(x).arg(y).arg(z);
+ } else {
+ label = QStringLiteral("No selection");
+ }
+
+ return label;
+}
+//! [2]
+
+void DataSource::clearData()
+{
+ for (int i(0); i < m_data.size(); i++) {
+ QSurfaceDataArray &array = m_data[i];
+ for (int j(0); j < array.size(); j++)
+ delete array[j];
+ array.clear();
+ }
+}
diff --git a/examples/datavisualization/qmloscilloscope/datasource.h b/examples/datavisualization/qmloscilloscope/datasource.h
new file mode 100644
index 00000000..51d3e8e0
--- /dev/null
+++ b/examples/datavisualization/qmloscilloscope/datasource.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** 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
+**
+****************************************************************************/
+
+#ifndef DATASOURCE_H
+#define DATASOURCE_H
+
+#include <QtDataVisualization>
+#include <QObject>
+
+class QQuickView;
+
+using namespace QtDataVisualization;
+
+class DataSource : public QObject
+{
+ Q_OBJECT
+public:
+ explicit DataSource(QObject *parent = 0);
+ virtual ~DataSource();
+
+ //! [0]
+public slots:
+ void generateData(int cacheCount, int rowCount, int columnCount,
+ float xMin, float xMax, float yMin, float yMax, float zMin, float zMax);
+
+ void update(QSurface3DSeries *series);
+
+ QString selectionLabel(QSurface3DSeries *series, QValue3DAxis *axisX,
+ QValue3DAxis *axisY, QValue3DAxis *axisZ);
+ //! [0]
+private:
+ void clearData();
+
+ QVector<QSurfaceDataArray> m_data;
+ int m_index;
+ QSurfaceDataArray *m_resetArray;
+};
+
+#endif
diff --git a/examples/datavisualization/qmloscilloscope/doc/images/qmloscilloscope-example.png b/examples/datavisualization/qmloscilloscope/doc/images/qmloscilloscope-example.png
new file mode 100644
index 00000000..697f391e
--- /dev/null
+++ b/examples/datavisualization/qmloscilloscope/doc/images/qmloscilloscope-example.png
Binary files differ
diff --git a/examples/datavisualization/qmloscilloscope/doc/src/qmloscilloscope.qdoc b/examples/datavisualization/qmloscilloscope/doc/src/qmloscilloscope.qdoc
new file mode 100644
index 00000000..9fdcd8d2
--- /dev/null
+++ b/examples/datavisualization/qmloscilloscope/doc/src/qmloscilloscope.qdoc
@@ -0,0 +1,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
+*/
diff --git a/examples/datavisualization/qmloscilloscope/main.cpp b/examples/datavisualization/qmloscilloscope/main.cpp
new file mode 100644
index 00000000..dd7f7a30
--- /dev/null
+++ b/examples/datavisualization/qmloscilloscope/main.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** 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
+**
+****************************************************************************/
+
+#include "datasource.h"
+#include "qtquick2applicationviewer.h"
+#include <QtDataVisualization/qutils.h>
+
+#include <QtGui/QGuiApplication>
+#include <QtCore/QDir>
+#include <QtQml/QQmlContext>
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ QtQuick2ApplicationViewer viewer;
+
+ // Enable antialiasing
+ viewer.setFormat(QtDataVisualization::qDefaultSurfaceFormat());
+
+ // The following are needed to make examples run without having to install the module
+ // in desktop environments.
+#ifdef Q_OS_WIN
+ QString extraImportPath(QStringLiteral("%1/../../../../%2"));
+#else
+ QString extraImportPath(QStringLiteral("%1/../../../%2"));
+#endif
+ viewer.addImportPath(extraImportPath.arg(QGuiApplication::applicationDirPath(),
+ QString::fromLatin1("qml")));
+
+ viewer.setTitle(QStringLiteral("Oscilloscope example"));
+
+ //! [0]
+ DataSource dataSource;
+ viewer.rootContext()->setContextProperty("dataSource", &dataSource);
+ //! [0]
+
+ viewer.setSource(QUrl("qrc:/qml/qmloscilloscope/main.qml"));
+ viewer.setResizeMode(QQuickView::SizeRootObjectToView);
+ viewer.show();
+
+ return app.exec();
+}
diff --git a/examples/datavisualization/qmloscilloscope/qml/qmloscilloscope/NewButton.qml b/examples/datavisualization/qmloscilloscope/qml/qmloscilloscope/NewButton.qml
new file mode 100644
index 00000000..e4fb99d2
--- /dev/null
+++ b/examples/datavisualization/qmloscilloscope/qml/qmloscilloscope/NewButton.qml
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** 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
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+
+Item {
+ id: newbutton
+
+ property alias text: buttonText.text
+
+ signal clicked
+
+ implicitWidth: buttonText.implicitWidth + 5
+ implicitHeight: buttonText.implicitHeight + 10
+
+ Button {
+ id: buttonText
+ width: parent.width
+ height: parent.height
+
+ style: ButtonStyle {
+ label: Component {
+ Text {
+ text: buttonText.text
+ clip: true
+ wrapMode: Text.WordWrap
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ anchors.fill: parent
+ }
+ }
+ }
+ onClicked: newbutton.clicked()
+ }
+}
diff --git a/examples/datavisualization/qmloscilloscope/qml/qmloscilloscope/main.qml b/examples/datavisualization/qmloscilloscope/qml/qmloscilloscope/main.qml
new file mode 100644
index 00000000..b9284777
--- /dev/null
+++ b/examples/datavisualization/qmloscilloscope/qml/qmloscilloscope/main.qml
@@ -0,0 +1,289 @@
+/****************************************************************************
+**
+** 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
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Layouts 1.0
+import QtQuick.Controls 1.0
+import QtDataVisualization 1.0
+import "."
+
+Item {
+ id: mainView
+ width: 1280
+ height: 1024
+
+ property int sampleColumns: sampleSlider.value
+ property int sampleRows: sampleColumns / 2
+ property int sampleCache: 24
+
+ onSampleRowsChanged: {
+ surfaceSeries.selectedPoint = surfaceSeries.invalidSelectionPosition
+ generateData()
+ }
+
+ Item {
+ id: dataView
+ anchors.bottom: parent.bottom
+ width: parent.width
+ height: parent.height - buttonLayout.height
+
+ Surface3D {
+ id: surfaceGraph
+
+ width: dataView.width
+ height: dataView.height
+ shadowQuality: AbstractGraph3D.ShadowQualityNone
+ selectionMode: AbstractGraph3D.SelectionSlice | AbstractGraph3D.SelectionItemAndRow
+
+ axisX.labelFormat: "%d ms"
+ axisY.labelFormat: "%d W"
+ axisZ.labelFormat: "%d mV"
+ axisX.min: 0
+ axisY.min: 0
+ axisZ.min: 0
+ axisX.max: 1000
+ axisY.max: 100
+ axisZ.max: 800
+ axisX.segmentCount: 4
+ axisY.segmentCount: 4
+ axisZ.segmentCount: 4
+
+ //! [0]
+ Surface3DSeries {
+ id: surfaceSeries
+ drawMode: Surface3DSeries.DrawSurface;
+ flatShadingEnabled: false;
+ meshSmooth: true
+ itemLabelFormat: ""
+
+ onSelectedPointChanged: mainView.updateSelectionLabel()
+ }
+ //! [0]
+
+ //! [2]
+ Component.onCompleted: mainView.generateData()
+ //! [2]
+ }
+ }
+
+ //! [3]
+ Timer {
+ id: refreshTimer
+ interval: 1000 / frequencySlider.value
+ running: true
+ repeat: true
+ onTriggered: {
+ dataSource.update(surfaceSeries)
+ mainView.updateSelectionLabel()
+ }
+ }
+ //! [3]
+
+ Rectangle {
+ width: parent.width
+ height: flatShadingToggle.height
+ anchors.left: parent.left
+ anchors.top: parent.top
+ color: surfaceGraph.theme.backgroundColor
+
+ RowLayout {
+ id: buttonLayout
+ Layout.minimumHeight: flatShadingToggle.height
+ anchors.fill: parent
+ spacing: 0
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.minimumWidth: samplesText.implicitWidth + 120
+ Layout.maximumWidth: samplesText.implicitWidth + 120
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+
+ border.color: "gray"
+ border.width: 1
+ radius: 4
+
+ RowLayout {
+ anchors.fill: parent
+ anchors.margins: parent.border.width + 1
+
+ Slider {
+ id: sampleSlider
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+ Layout.minimumWidth: 100
+ minimumValue: mainView.sampleCache * 2
+ maximumValue: minimumValue * 10
+ stepSize: mainView.sampleCache
+ updateValueWhileDragging: false
+ value: minimumValue * 2
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.minimumWidth: samplesText.implicitWidth + 10
+ Layout.maximumWidth: samplesText.implicitWidth + 10
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+
+ Text {
+ id: samplesText
+ text: "Samples: " + (mainView.sampleRows * mainView.sampleColumns)
+ anchors.fill: parent
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.minimumWidth: frequencyText.implicitWidth + 120
+ Layout.maximumWidth: frequencyText.implicitWidth + 120
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+
+ border.color: "gray"
+ border.width: 1
+ radius: 4
+
+ RowLayout {
+ anchors.fill: parent
+ anchors.margins: parent.border.width + 1
+
+ Slider {
+ id: frequencySlider
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+ Layout.minimumWidth: 100
+ minimumValue: 2
+ maximumValue: 60
+ stepSize: 2
+ updateValueWhileDragging: true
+ value: 30
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.minimumWidth: frequencyText.implicitWidth + 10
+ Layout.maximumWidth: frequencyText.implicitWidth + 10
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+
+ Text {
+ id: frequencyText
+ text: "Target freq: " + frequencySlider.value + " Hz"
+ anchors.fill: parent
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ Layout.minimumWidth: selectionText.implicitWidth + 10
+ Layout.maximumWidth: selectionText.implicitWidth + 10
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
+
+ border.color: "gray"
+ border.width: 1
+ radius: 4
+
+ Text {
+ id: selectionText
+ text: "No selection"
+ anchors.fill: parent
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ }
+ }
+
+ NewButton {
+ id: flatShadingToggle
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+
+ text: "Show Flat"
+ enabled: surfaceSeries.flatShadingSupported
+
+ onClicked: {
+ if (surfaceSeries.flatShadingEnabled === true) {
+ surfaceSeries.flatShadingEnabled = false;
+ text = "Show Flat"
+ } else {
+ surfaceSeries.flatShadingEnabled = true;
+ text = "Show Smooth"
+ }
+ }
+ }
+
+ NewButton {
+ id: surfaceGridToggle
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+
+ text: "Show Surface Grid"
+
+ onClicked: {
+ if (surfaceSeries.drawMode & Surface3DSeries.DrawWireframe) {
+ surfaceSeries.drawMode &= ~Surface3DSeries.DrawWireframe;
+ text = "Show Surface Grid"
+ } else {
+ surfaceSeries.drawMode |= Surface3DSeries.DrawWireframe;
+ text = "Hide Surface Grid"
+ }
+ }
+ }
+
+ NewButton {
+ id: exitButton
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+
+ text: "Quit"
+
+ onClicked: Qt.quit(0);
+ }
+ }
+ }
+
+ //! [1]
+ function updateSelectionLabel() {
+ selectionText.text = dataSource.selectionLabel(surfaceSeries,
+ surfaceGraph.axisX,
+ surfaceGraph.axisY,
+ surfaceGraph.axisZ)
+ }
+ //! [1]
+
+ //! [4]
+ function generateData() {
+ dataSource.generateData(mainView.sampleCache, mainView.sampleRows,
+ mainView.sampleColumns, surfaceGraph.axisX.min,
+ surfaceGraph.axisX.max, surfaceGraph.axisY.min,
+ surfaceGraph.axisY.max, surfaceGraph.axisZ.min,
+ surfaceGraph.axisZ.max)
+ }
+ //! [4]
+}
diff --git a/examples/datavisualization/qmloscilloscope/qmloscilloscope.desktop b/examples/datavisualization/qmloscilloscope/qmloscilloscope.desktop
new file mode 100644
index 00000000..bd8e8325
--- /dev/null
+++ b/examples/datavisualization/qmloscilloscope/qmloscilloscope.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=qmloscilloscope
+Exec=/opt/qmloscilloscope/bin/qmloscilloscope
+Icon=qmloscilloscope64
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/datavisualization/qmloscilloscope/qmloscilloscope.pro b/examples/datavisualization/qmloscilloscope/qmloscilloscope.pro
new file mode 100644
index 00000000..c1e556ae
--- /dev/null
+++ b/examples/datavisualization/qmloscilloscope/qmloscilloscope.pro
@@ -0,0 +1,24 @@
+!include( ../examples.pri ) {
+ error( "Couldn't find the examples.pri file!" )
+}
+
+QT += datavisualization
+
+# Add more folders to ship with the application, here
+folder_01.source = qml/qmloscilloscope
+folder_01.target = qml
+DEPLOYMENTFOLDERS = folder_01
+
+# Additional import path used to resolve QML modules in Creator's code model
+QML_IMPORT_PATH =
+
+# The .cpp file which was generated for your project. Feel free to hack it.
+SOURCES += main.cpp \
+ datasource.cpp
+HEADERS += datasource.h
+
+# Please do not modify the following two lines. Required for deployment.
+include(qtquick2applicationviewer/qtquick2applicationviewer.pri)
+qtcAddDeployment()
+
+RESOURCES += qmloscilloscope.qrc
diff --git a/examples/datavisualization/qmloscilloscope/qmloscilloscope.qrc b/examples/datavisualization/qmloscilloscope/qmloscilloscope.qrc
new file mode 100644
index 00000000..a2358789
--- /dev/null
+++ b/examples/datavisualization/qmloscilloscope/qmloscilloscope.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/">
+ <file>qml/qmloscilloscope/main.qml</file>
+ <file>qml/qmloscilloscope/NewButton.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/datavisualization/qmloscilloscope/qmloscilloscope64.png b/examples/datavisualization/qmloscilloscope/qmloscilloscope64.png
new file mode 100644
index 00000000..707d5c4e
--- /dev/null
+++ b/examples/datavisualization/qmloscilloscope/qmloscilloscope64.png
Binary files differ
diff --git a/examples/datavisualization/qmloscilloscope/qtquick2applicationviewer/qtquick2applicationviewer.cpp b/examples/datavisualization/qmloscilloscope/qtquick2applicationviewer/qtquick2applicationviewer.cpp
new file mode 100644
index 00000000..10709d7a
--- /dev/null
+++ b/examples/datavisualization/qmloscilloscope/qtquick2applicationviewer/qtquick2applicationviewer.cpp
@@ -0,0 +1,81 @@
+// checksum 0x4f6f version 0x90005
+/*
+ This file was generated by the Qt Quick 2 Application wizard of Qt Creator.
+ QtQuick2ApplicationViewer is a convenience class containing mobile device specific
+ code such as screen orientation handling. Also QML paths and debugging are
+ handled here.
+ It is recommended not to modify this file, since newer versions of Qt Creator
+ may offer an updated version of it.
+*/
+
+#include "qtquick2applicationviewer.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDir>
+#include <QtQml/QQmlEngine>
+
+class QtQuick2ApplicationViewerPrivate
+{
+ QString mainQmlFile;
+ friend class QtQuick2ApplicationViewer;
+ static QString adjustPath(const QString &path);
+};
+
+QString QtQuick2ApplicationViewerPrivate::adjustPath(const QString &path)
+{
+#if defined(Q_OS_MAC)
+ if (!QDir::isAbsolutePath(path))
+ return QString::fromLatin1("%1/../Resources/%2")
+ .arg(QCoreApplication::applicationDirPath(), path);
+#elif defined(Q_OS_BLACKBERRY)
+ if (!QDir::isAbsolutePath(path))
+ return QString::fromLatin1("app/native/%1").arg(path);
+#elif !defined(Q_OS_ANDROID)
+ QString pathInInstallDir =
+ QString::fromLatin1("%1/../%2").arg(QCoreApplication::applicationDirPath(), path);
+ if (QFileInfo(pathInInstallDir).exists())
+ return pathInInstallDir;
+ pathInInstallDir =
+ QString::fromLatin1("%1/%2").arg(QCoreApplication::applicationDirPath(), path);
+ if (QFileInfo(pathInInstallDir).exists())
+ return pathInInstallDir;
+#endif
+ return path;
+}
+
+QtQuick2ApplicationViewer::QtQuick2ApplicationViewer(QWindow *parent)
+ : QQuickView(parent)
+ , d(new QtQuick2ApplicationViewerPrivate())
+{
+ connect(engine(), SIGNAL(quit()), SLOT(close()));
+ setResizeMode(QQuickView::SizeRootObjectToView);
+}
+
+QtQuick2ApplicationViewer::~QtQuick2ApplicationViewer()
+{
+ delete d;
+}
+
+void QtQuick2ApplicationViewer::setMainQmlFile(const QString &file)
+{
+ d->mainQmlFile = QtQuick2ApplicationViewerPrivate::adjustPath(file);
+#ifdef Q_OS_ANDROID
+ setSource(QUrl(QLatin1String("assets:/")+d->mainQmlFile));
+#else
+ setSource(QUrl::fromLocalFile(d->mainQmlFile));
+#endif
+}
+
+void QtQuick2ApplicationViewer::addImportPath(const QString &path)
+{
+ engine()->addImportPath(QtQuick2ApplicationViewerPrivate::adjustPath(path));
+}
+
+void QtQuick2ApplicationViewer::showExpanded()
+{
+#if defined(Q_WS_SIMULATOR) || defined(Q_OS_QNX)
+ showFullScreen();
+#else
+ show();
+#endif
+}
diff --git a/examples/datavisualization/qmloscilloscope/qtquick2applicationviewer/qtquick2applicationviewer.h b/examples/datavisualization/qmloscilloscope/qtquick2applicationviewer/qtquick2applicationviewer.h
new file mode 100644
index 00000000..cf66f140
--- /dev/null
+++ b/examples/datavisualization/qmloscilloscope/qtquick2applicationviewer/qtquick2applicationviewer.h
@@ -0,0 +1,33 @@
+// checksum 0xfde6 version 0x90005
+/*
+ This file was generated by the Qt Quick 2 Application wizard of Qt Creator.
+ QtQuick2ApplicationViewer is a convenience class containing mobile device specific
+ code such as screen orientation handling. Also QML paths and debugging are
+ handled here.
+ It is recommended not to modify this file, since newer versions of Qt Creator
+ may offer an updated version of it.
+*/
+
+#ifndef QTQUICK2APPLICATIONVIEWER_H
+#define QTQUICK2APPLICATIONVIEWER_H
+
+#include <QtQuick/QQuickView>
+
+class QtQuick2ApplicationViewer : public QQuickView
+{
+ Q_OBJECT
+
+public:
+ explicit QtQuick2ApplicationViewer(QWindow *parent = 0);
+ virtual ~QtQuick2ApplicationViewer();
+
+ void setMainQmlFile(const QString &file);
+ void addImportPath(const QString &path);
+
+ void showExpanded();
+
+private:
+ class QtQuick2ApplicationViewerPrivate *d;
+};
+
+#endif // QTQUICK2APPLICATIONVIEWER_H
diff --git a/examples/datavisualization/qmloscilloscope/qtquick2applicationviewer/qtquick2applicationviewer.pri b/examples/datavisualization/qmloscilloscope/qtquick2applicationviewer/qtquick2applicationviewer.pri
new file mode 100644
index 00000000..e5f7990f
--- /dev/null
+++ b/examples/datavisualization/qmloscilloscope/qtquick2applicationviewer/qtquick2applicationviewer.pri
@@ -0,0 +1,180 @@
+# checksum 0x7b0d version 0x90005
+# This file was generated by the Qt Quick 2 Application wizard of Qt Creator.
+# The code below adds the QtQuick2ApplicationViewer to the project and handles
+# the activation of QML debugging.
+# It is recommended not to modify this file, since newer versions of Qt Creator
+# may offer an updated version of it.
+
+QT += qml quick
+
+SOURCES += $$PWD/qtquick2applicationviewer.cpp
+HEADERS += $$PWD/qtquick2applicationviewer.h
+INCLUDEPATH += $$PWD
+# This file was generated by an application wizard of Qt Creator.
+# The code below handles deployment to Android and Maemo, aswell as copying
+# of the application data to shadow build directories on desktop.
+# It is recommended not to modify this file, since newer versions of Qt Creator
+# may offer an updated version of it.
+
+defineTest(qtcAddDeployment) {
+for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ greaterThan(QT_MAJOR_VERSION, 4) {
+ itemsources = $${item}.files
+ } else {
+ itemsources = $${item}.sources
+ }
+ $$itemsources = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath= $$eval($${deploymentfolder}.target)
+ export($$itemsources)
+ export($$itempath)
+ DEPLOYMENT += $$item
+}
+
+MAINPROFILEPWD = $$PWD
+
+android-no-sdk {
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ itemfiles = $${item}.files
+ $$itemfiles = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath = /data/user/qt/$$eval($${deploymentfolder}.target)
+ export($$itemfiles)
+ export($$itempath)
+ INSTALLS += $$item
+ }
+
+ target.path = /data/user/qt
+
+ export(target.path)
+ INSTALLS += target
+} else:android {
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ itemfiles = $${item}.files
+ $$itemfiles = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath = /assets/$$eval($${deploymentfolder}.target)
+ export($$itemfiles)
+ export($$itempath)
+ INSTALLS += $$item
+ }
+
+ x86 {
+ target.path = /libs/x86
+ } else: armeabi-v7a {
+ target.path = /libs/armeabi-v7a
+ } else {
+ target.path = /libs/armeabi
+ }
+
+ export(target.path)
+ INSTALLS += target
+} else:win32 {
+ copyCommand =
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
+ source = $$replace(source, /, \\)
+ sourcePathSegments = $$split(source, \\)
+ target = $$OUT_PWD/$$eval($${deploymentfolder}.target)/$$last(sourcePathSegments)
+ target = $$replace(target, /, \\)
+ target ~= s,\\\\\\.?\\\\,\\,
+ !isEqual(source,$$target) {
+ !isEmpty(copyCommand):copyCommand += &&
+ isEqual(QMAKE_DIR_SEP, \\) {
+ copyCommand += $(COPY_DIR) \"$$source\" \"$$target\"
+ } else {
+ source = $$replace(source, \\\\, /)
+ target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
+ target = $$replace(target, \\\\, /)
+ copyCommand += test -d \"$$target\" || mkdir -p \"$$target\" && cp -r \"$$source\" \"$$target\"
+ }
+ }
+ }
+ !isEmpty(copyCommand) {
+ copyCommand = @echo Copying application data... && $$copyCommand
+ copydeploymentfolders.commands = $$copyCommand
+ first.depends = $(first) copydeploymentfolders
+ export(first.depends)
+ export(copydeploymentfolders.commands)
+ QMAKE_EXTRA_TARGETS += first copydeploymentfolders
+ }
+} else:unix {
+ maemo5 {
+ desktopfile.files = $${TARGET}.desktop
+ desktopfile.path = /usr/share/applications/hildon
+ icon.files = $${TARGET}64.png
+ icon.path = /usr/share/icons/hicolor/64x64/apps
+ } else:!isEmpty(MEEGO_VERSION_MAJOR) {
+ desktopfile.files = $${TARGET}_harmattan.desktop
+ desktopfile.path = /usr/share/applications
+ icon.files = $${TARGET}80.png
+ icon.path = /usr/share/icons/hicolor/80x80/apps
+ } else { # Assumed to be a Desktop Unix
+ copyCommand =
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
+ source = $$replace(source, \\\\, /)
+ macx {
+ target = $$OUT_PWD/$${TARGET}.app/Contents/Resources/$$eval($${deploymentfolder}.target)
+ } else {
+ target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
+ }
+ target = $$replace(target, \\\\, /)
+ sourcePathSegments = $$split(source, /)
+ targetFullPath = $$target/$$last(sourcePathSegments)
+ targetFullPath ~= s,/\\.?/,/,
+ !isEqual(source,$$targetFullPath) {
+ !isEmpty(copyCommand):copyCommand += &&
+ copyCommand += $(MKDIR) \"$$target\"
+ copyCommand += && $(COPY_DIR) \"$$source\" \"$$target\"
+ }
+ }
+ !isEmpty(copyCommand) {
+ copyCommand = @echo Copying application data... && $$copyCommand
+ copydeploymentfolders.commands = $$copyCommand
+ first.depends = $(first) copydeploymentfolders
+ export(first.depends)
+ export(copydeploymentfolders.commands)
+ QMAKE_EXTRA_TARGETS += first copydeploymentfolders
+ }
+ }
+ !isEmpty(target.path) {
+ installPrefix = $${target.path}
+ } else {
+ installPrefix = /opt/$${TARGET}
+ }
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ itemfiles = $${item}.files
+ $$itemfiles = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath = $${installPrefix}/$$eval($${deploymentfolder}.target)
+ export($$itemfiles)
+ export($$itempath)
+ INSTALLS += $$item
+ }
+
+ !isEmpty(desktopfile.path) {
+ export(icon.files)
+ export(icon.path)
+ export(desktopfile.files)
+ export(desktopfile.path)
+ INSTALLS += icon desktopfile
+ }
+
+ isEmpty(target.path) {
+ target.path = $${installPrefix}/bin
+ export(target.path)
+ }
+ INSTALLS += target
+}
+
+export (ICON)
+export (INSTALLS)
+export (DEPLOYMENT)
+export (LIBS)
+export (QMAKE_EXTRA_TARGETS)
+}