@@ -0,0 +1,85 | |||
|
1 | /**************************************************************************** | |
|
2 | ** | |
|
3 | ** Copyright (C) 2012 Digia Plc | |
|
4 | ** All rights reserved. | |
|
5 | ** For any questions to Digia, please use contact form at http://qt.digia.com | |
|
6 | ** | |
|
7 | ** This file is part of the Qt Commercial Charts Add-on. | |
|
8 | ** | |
|
9 | ** $QT_BEGIN_LICENSE$ | |
|
10 | ** Licensees holding valid Qt Commercial licenses may use this file in | |
|
11 | ** accordance with the Qt Commercial License Agreement provided with the | |
|
12 | ** Software or, alternatively, in accordance with the terms contained in | |
|
13 | ** a written agreement between you and Digia. | |
|
14 | ** | |
|
15 | ** If you have questions regarding the use of this file, please use | |
|
16 | ** contact form at http://qt.digia.com | |
|
17 | ** $QT_END_LICENSE$ | |
|
18 | ** | |
|
19 | ****************************************************************************/ | |
|
20 | ||
|
21 | import QtQuick 1.0 | |
|
22 | ||
|
23 | Column { | |
|
24 | spacing: 5 | |
|
25 | signal openGLEnabled(bool enabled) | |
|
26 | signal animationsEnabled(bool enabled) | |
|
27 | signal seriesTypeChanged(string type) | |
|
28 | signal refreshRateChanged(variant rate); | |
|
29 | signal signalSourceChanged(string source, int signalCount, int sampleCount); | |
|
30 | ||
|
31 | Text { | |
|
32 | text: "Oscilloscope" | |
|
33 | font.pointSize: 18 | |
|
34 | } | |
|
35 | ||
|
36 | MultiButton { | |
|
37 | id: signalSourceButton | |
|
38 | text: "Signal source: " | |
|
39 | items: ["sin", "linear"] | |
|
40 | currentSelection: 0 | |
|
41 | onSelectionChanged: signalSourceChanged( | |
|
42 | selection, | |
|
43 | 5, | |
|
44 | sampleCountButton.items[sampleCountButton.currentSelection]); | |
|
45 | } | |
|
46 | ||
|
47 | MultiButton { | |
|
48 | id: sampleCountButton | |
|
49 | text: "Samples: " | |
|
50 | items: [6, 128, 1024, 10000] | |
|
51 | currentSelection: 2 | |
|
52 | onSelectionChanged: signalSourceChanged( | |
|
53 | signalSourceButton.items[signalSourceButton.currentSelection], | |
|
54 | 5, | |
|
55 | selection); | |
|
56 | } | |
|
57 | ||
|
58 | MultiButton { | |
|
59 | text: "Graph: " | |
|
60 | items: ["line", "spline", "scatter"] | |
|
61 | currentSelection: 0 | |
|
62 | onSelectionChanged: seriesTypeChanged(items[currentSelection]); | |
|
63 | } | |
|
64 | ||
|
65 | MultiButton { | |
|
66 | text: "Refresh rate: " | |
|
67 | items: [1, 24, 60, 100] | |
|
68 | currentSelection: 2 | |
|
69 | onSelectionChanged: refreshRateChanged(items[currentSelection]); | |
|
70 | } | |
|
71 | ||
|
72 | MultiButton { | |
|
73 | text: "OpenGL: " | |
|
74 | items: ["OFF", "ON"] | |
|
75 | currentSelection: 0 | |
|
76 | onSelectionChanged: openGLEnabled(currentSelection == 1); | |
|
77 | } | |
|
78 | ||
|
79 | MultiButton { | |
|
80 | text: "Animations: " | |
|
81 | items: ["OFF", "ON"] | |
|
82 | currentSelection: 0 | |
|
83 | onSelectionChanged: animationsEnabled(currentSelection == 1); | |
|
84 | } | |
|
85 | } |
@@ -0,0 +1,47 | |||
|
1 | /**************************************************************************** | |
|
2 | ** | |
|
3 | ** Copyright (C) 2012 Digia Plc | |
|
4 | ** All rights reserved. | |
|
5 | ** For any questions to Digia, please use contact form at http://qt.digia.com | |
|
6 | ** | |
|
7 | ** This file is part of the Qt Commercial Charts Add-on. | |
|
8 | ** | |
|
9 | ** $QT_BEGIN_LICENSE$ | |
|
10 | ** Licensees holding valid Qt Commercial licenses may use this file in | |
|
11 | ** accordance with the Qt Commercial License Agreement provided with the | |
|
12 | ** Software or, alternatively, in accordance with the terms contained in | |
|
13 | ** a written agreement between you and Digia. | |
|
14 | ** | |
|
15 | ** If you have questions regarding the use of this file, please use | |
|
16 | ** contact form at http://qt.digia.com | |
|
17 | ** $QT_END_LICENSE$ | |
|
18 | ** | |
|
19 | ****************************************************************************/ | |
|
20 | ||
|
21 | import QtQuick 1.0 | |
|
22 | ||
|
23 | Rectangle { | |
|
24 | id: button | |
|
25 | width: 105 | |
|
26 | height: 33 | |
|
27 | border.color: "gray" | |
|
28 | radius: 5 | |
|
29 | property string text: "Option: " | |
|
30 | property variant items: ["first"] | |
|
31 | property int currentSelection: 0 | |
|
32 | signal selectionChanged(variant selection) | |
|
33 | ||
|
34 | Text { | |
|
35 | id: buttonText | |
|
36 | anchors.centerIn: parent | |
|
37 | text: button.text + button.items[currentSelection] | |
|
38 | } | |
|
39 | ||
|
40 | MouseArea { | |
|
41 | anchors.fill: parent | |
|
42 | onClicked: { | |
|
43 | currentSelection = (currentSelection + 1) % items.length; | |
|
44 | selectionChanged(button.items[currentSelection]); | |
|
45 | } | |
|
46 | } | |
|
47 | } |
@@ -0,0 +1,98 | |||
|
1 | /**************************************************************************** | |
|
2 | ** | |
|
3 | ** Copyright (C) 2012 Digia Plc | |
|
4 | ** All rights reserved. | |
|
5 | ** For any questions to Digia, please use contact form at http://qt.digia.com | |
|
6 | ** | |
|
7 | ** This file is part of the Qt Commercial Charts Add-on. | |
|
8 | ** | |
|
9 | ** $QT_BEGIN_LICENSE$ | |
|
10 | ** Licensees holding valid Qt Commercial licenses may use this file in | |
|
11 | ** accordance with the Qt Commercial License Agreement provided with the | |
|
12 | ** Software or, alternatively, in accordance with the terms contained in | |
|
13 | ** a written agreement between you and Digia. | |
|
14 | ** | |
|
15 | ** If you have questions regarding the use of this file, please use | |
|
16 | ** contact form at http://qt.digia.com | |
|
17 | ** $QT_END_LICENSE$ | |
|
18 | ** | |
|
19 | ****************************************************************************/ | |
|
20 | ||
|
21 | import QtQuick 1.0 | |
|
22 | import QtCommercial.Chart 1.0 | |
|
23 | ||
|
24 | ChartView { | |
|
25 | id: chartView | |
|
26 | animationOptions: ChartView.NoAnimation | |
|
27 | ||
|
28 | ValuesAxis { | |
|
29 | id: axisY | |
|
30 | min: -1 | |
|
31 | max: 3 | |
|
32 | } | |
|
33 | ||
|
34 | ValuesAxis { | |
|
35 | id: axisX | |
|
36 | min: 0 | |
|
37 | max: 1000 | |
|
38 | } | |
|
39 | ||
|
40 | LineSeries { | |
|
41 | id: lineSeries1 | |
|
42 | name: "signal 1" | |
|
43 | } | |
|
44 | LineSeries { | |
|
45 | id: lineSeries2 | |
|
46 | name: "signal 2" | |
|
47 | } | |
|
48 | ||
|
49 | Component.onCompleted: { | |
|
50 | chartView.setAxisX(axisX, lineSeries1); | |
|
51 | chartView.setAxisY(axisY, lineSeries1); | |
|
52 | chartView.setAxisX(axisX, lineSeries2); | |
|
53 | chartView.setAxisY(axisY, lineSeries2); | |
|
54 | } | |
|
55 | ||
|
56 | Timer { | |
|
57 | id: refreshTimer | |
|
58 | interval: 1 / 60 * 1000 // 60 Hz | |
|
59 | running: true | |
|
60 | repeat: true | |
|
61 | onTriggered: { | |
|
62 | dataSource.update(chartView.series(0)); | |
|
63 | dataSource.update(chartView.series(1)); | |
|
64 | } | |
|
65 | } | |
|
66 | ||
|
67 | function changeSeriesType(type) { | |
|
68 | chartView.series(1).destroy(); | |
|
69 | chartView.series(0).destroy(); | |
|
70 | var seriesCount = 2; | |
|
71 | for (var i = 0; i < seriesCount; i++) { | |
|
72 | var series; | |
|
73 | if (type == "line") { | |
|
74 | series = scopeView.createSeries(ChartView.SeriesTypeLine, "signal " + (i + 1)); | |
|
75 | } else if (type == "spline") { | |
|
76 | series = chartView.createSeries(ChartView.SeriesTypeSpline, "signal " + (i + 1)); | |
|
77 | } else { | |
|
78 | series = chartView.createSeries(ChartView.SeriesTypeScatter, "signal " + (i + 1)); | |
|
79 | series.markerSize = 3; | |
|
80 | series.borderColor = "transparent"; | |
|
81 | } | |
|
82 | chartView.setAxisX(axisX, series); | |
|
83 | chartView.setAxisY(axisY, series); | |
|
84 | } | |
|
85 | } | |
|
86 | ||
|
87 | function setAnimations(enabled) { | |
|
88 | if (enabled) | |
|
89 | scopeView.animationOptions = ChartView.SeriesAnimations; | |
|
90 | else | |
|
91 | scopeView.animationOptions = ChartView.NoAnimation; | |
|
92 | } | |
|
93 | ||
|
94 | function changeRefreshRate(rate) { | |
|
95 | console.log("rate " + rate); | |
|
96 | refreshTimer.interval = 1 / Number(rate) * 1000; | |
|
97 | } | |
|
98 | } |
@@ -20,36 +20,76 | |||
|
20 | 20 | |
|
21 | 21 | #include "datasource.h" |
|
22 | 22 | #include <QXYSeries> |
|
23 | #include <QAreaSeries> | |
|
24 | #include <QAbstractScrollArea> | |
|
25 | #include <QGLWidget> | |
|
23 | 26 | #include <QDebug> |
|
24 | 27 | |
|
25 | 28 | QTCOMMERCIALCHART_USE_NAMESPACE |
|
26 | 29 | |
|
27 | DataSource::DataSource(QObject *parent) : | |
|
30 | DataSource::DataSource(QAbstractScrollArea *appViewer, QObject *parent) : | |
|
31 | m_appViewer(appViewer), | |
|
28 | 32 | QObject(parent), |
|
29 |
m_index( |
|
|
33 | m_index(-1) | |
|
30 | 34 | { |
|
31 | const int rowCount = 5; | |
|
32 | const int colCount = 1024; | |
|
35 | // generate | |
|
36 | generateData(0, 5, 1024); | |
|
37 | } | |
|
38 | ||
|
39 | void DataSource::update(QAbstractSeries *series) | |
|
40 | { | |
|
41 | QXYSeries *xySeries = qobject_cast<QXYSeries *>(series); | |
|
42 | Q_ASSERT(xySeries); | |
|
43 | ||
|
44 | m_index++; | |
|
45 | if (m_index > m_data.count() - 1) | |
|
46 | m_index = 0; | |
|
47 | ||
|
48 | QList<QPointF> points = m_data.at(m_index); | |
|
49 | // Use replace instead of clear + append, it's optimized for performance | |
|
50 | xySeries->replace(points); | |
|
51 | } | |
|
52 | ||
|
53 | void DataSource::generateData(int type, int rowCount, int colCount) | |
|
54 | { | |
|
55 | qDebug() << "DataSource::generateData:" << type << rowCount << colCount; | |
|
33 | 56 | |
|
57 | // Remove previous data | |
|
58 | foreach (QList<QPointF> row, m_data) | |
|
59 | row.clear(); | |
|
60 | m_data.clear(); | |
|
61 | ||
|
62 | // Append the new data depending on the type | |
|
34 | 63 | for (int i(0); i < rowCount; i++) { |
|
35 | 64 | QList<QPointF> points; |
|
36 | 65 | for (int j(0); j < colCount; j++) { |
|
37 |
qreal x |
|
|
38 | qreal y = sin(3.14159265358979 / 50 * x) + 0.5 + (qreal) rand() / (qreal) RAND_MAX; | |
|
66 | qreal x(0); | |
|
67 | qreal y(0); | |
|
68 | switch (type) { | |
|
69 | case 0: | |
|
70 | // data with sin + random component | |
|
71 | y = sin(3.14159265358979 / 50 * j) + 0.5 + (qreal) rand() / (qreal) RAND_MAX; | |
|
72 | x = j; | |
|
73 | break; | |
|
74 | case 1: | |
|
75 | // linear data | |
|
76 | x = j; | |
|
77 | y = (qreal) i / 10; | |
|
78 | break; | |
|
79 | default: | |
|
80 | // unknown, do nothing | |
|
81 | break; | |
|
82 | } | |
|
39 | 83 | points.append(QPointF(x, y)); |
|
40 | 84 | } |
|
41 | 85 | m_data.append(points); |
|
42 | 86 | } |
|
43 | 87 | } |
|
44 | 88 | |
|
45 | void DataSource::update(QAbstractSeries *series) | |
|
89 | void DataSource::setOpenGL(bool enabled) | |
|
46 | 90 | { |
|
47 | QXYSeries *xySeries = qobject_cast<QXYSeries *>(series); | |
|
48 | Q_ASSERT(xySeries); | |
|
49 | ||
|
50 | QList<QPointF> points = m_data.at(m_index); | |
|
51 | //xySeries->clear(); | |
|
52 | //xySeries->append(points); | |
|
53 | xySeries->replace(points); | |
|
54 | m_index = (m_index + 1) % m_data.count(); | |
|
91 | if (enabled) | |
|
92 | m_appViewer->setViewport(new QGLWidget()); | |
|
93 | else | |
|
94 | m_appViewer->setViewport(0); | |
|
55 | 95 | } |
@@ -24,20 +24,25 | |||
|
24 | 24 | #include <QObject> |
|
25 | 25 | #include <QAbstractSeries> |
|
26 | 26 | |
|
27 | class QAbstractScrollArea; | |
|
28 | ||
|
27 | 29 | QTCOMMERCIALCHART_USE_NAMESPACE |
|
28 | 30 | |
|
29 | 31 | class DataSource : public QObject |
|
30 | 32 | { |
|
31 | 33 | Q_OBJECT |
|
32 | 34 | public: |
|
33 | explicit DataSource(QObject *parent = 0); | |
|
35 | explicit DataSource(QAbstractScrollArea *appViewer, QObject *parent = 0); | |
|
34 | 36 | |
|
35 | 37 | signals: |
|
36 | 38 | |
|
37 | 39 | public slots: |
|
40 | void generateData(int type, int rowCount, int colCount); | |
|
38 | 41 | void update(QAbstractSeries *series); |
|
42 | void setOpenGL(bool enabled); | |
|
39 | 43 | |
|
40 | 44 | private: |
|
45 | QAbstractScrollArea *m_appViewer; | |
|
41 | 46 | QList<QList<QPointF> > m_data; |
|
42 | 47 | int m_index; |
|
43 | 48 | }; |
@@ -21,7 +21,6 | |||
|
21 | 21 | #include <QtGui/QApplication> |
|
22 | 22 | #include <QDeclarativeEngine> |
|
23 | 23 | #include <QDeclarativeContext> |
|
24 | #include <QGLWidget> | |
|
25 | 24 | #include "qmlapplicationviewer.h" |
|
26 | 25 | #include "datasource.h" |
|
27 | 26 | |
@@ -30,12 +29,11 Q_DECL_EXPORT int main(int argc, char *argv[]) | |||
|
30 | 29 | QScopedPointer<QApplication> app(createApplication(argc, argv)); |
|
31 | 30 | QScopedPointer<QmlApplicationViewer> viewer(QmlApplicationViewer::create()); |
|
32 | 31 | |
|
33 | DataSource dataSource; | |
|
32 | DataSource dataSource(viewer.data()); | |
|
34 | 33 | viewer->rootContext()->setContextProperty("dataSource", &dataSource); |
|
35 | 34 | |
|
36 | 35 | viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto); |
|
37 | 36 | viewer->setSource(QUrl("qrc:/qml/qmloscilloscope/main.qml")); |
|
38 | viewer->setViewport(new QGLWidget()); | |
|
39 | 37 | viewer->showExpanded(); |
|
40 | 38 | |
|
41 | 39 | return app->exec(); |
@@ -19,54 +19,38 | |||
|
19 | 19 | ****************************************************************************/ |
|
20 | 20 | |
|
21 | 21 | import QtQuick 1.0 |
|
22 | import QtCommercial.Chart 1.0 | |
|
23 | 22 | |
|
24 | 23 | Rectangle { |
|
24 | id: main | |
|
25 | 25 | width: 400 |
|
26 | 26 | height: 300 |
|
27 | 27 | |
|
28 | ChartView { | |
|
29 |
id: c |
|
|
30 |
anchors. |
|
|
31 | title: "Oscilloscope" | |
|
32 | animationOptions: ChartView.NoAnimation | |
|
33 | ||
|
34 | ValuesAxis { | |
|
35 | id: axisY | |
|
36 | min: -1 | |
|
37 | max: 3 | |
|
38 | } | |
|
39 | ||
|
40 | ValuesAxis { | |
|
41 | id: axisX | |
|
42 | min: 0 | |
|
43 | max: 1000 | |
|
44 | } | |
|
45 | ||
|
46 | LineSeries { | |
|
47 | id: lineSeries1 | |
|
48 | name: "signal 1" | |
|
49 | } | |
|
50 | LineSeries { | |
|
51 | id: lineSeries2 | |
|
52 | name: "signal 2" | |
|
53 | } | |
|
54 | } | |
|
55 | ||
|
56 | Timer { | |
|
57 | interval: 16 // 60 Hz | |
|
58 | running: true | |
|
59 | repeat: true | |
|
60 | onTriggered: { | |
|
61 | dataSource.update(lineSeries1); | |
|
62 | dataSource.update(lineSeries2); | |
|
28 | ControlPanel { | |
|
29 | id: controlPanel | |
|
30 | anchors.top: parent.top | |
|
31 | anchors.topMargin: 10 | |
|
32 | anchors.bottom: parent.bottom | |
|
33 | anchors.left: parent.left | |
|
34 | anchors.leftMargin: 10 | |
|
35 | ||
|
36 | onSignalSourceChanged: { | |
|
37 | if (source == "sin") | |
|
38 | dataSource.generateData(0, signalCount, sampleCount); | |
|
39 | else | |
|
40 | dataSource.generateData(1, signalCount, sampleCount); | |
|
63 | 41 | } |
|
42 | onOpenGLEnabled: dataSource.setOpenGL(enabled); | |
|
43 | onAnimationsEnabled: scopeView.setAnimations(enabled); | |
|
44 | onSeriesTypeChanged: scopeView.changeSeriesType(type); | |
|
45 | onRefreshRateChanged: scopeView.changeRefreshRate(rate); | |
|
64 | 46 | } |
|
65 | 47 | |
|
66 | Component.onCompleted: { | |
|
67 | chartView.setAxisX(axisX, lineSeries1); | |
|
68 | chartView.setAxisY(axisY, lineSeries1); | |
|
69 | chartView.setAxisX(axisX, lineSeries2); | |
|
70 | chartView.setAxisY(axisY, lineSeries2); | |
|
48 | ScopeView { | |
|
49 | id: scopeView | |
|
50 | anchors.top: parent.top | |
|
51 | anchors.bottom: parent.bottom | |
|
52 | anchors.right: parent.right | |
|
53 | anchors.left: controlPanel.right | |
|
54 | height: main.height | |
|
71 | 55 | } |
|
72 | 56 | } |
General Comments 0
You need to be logged in to leave comments.
Login now