@@ -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 | #include "datasource.h" |
|
21 | #include "datasource.h" | |
22 | #include <QXYSeries> |
|
22 | #include <QXYSeries> | |
|
23 | #include <QAreaSeries> | |||
|
24 | #include <QAbstractScrollArea> | |||
|
25 | #include <QGLWidget> | |||
23 | #include <QDebug> |
|
26 | #include <QDebug> | |
24 |
|
27 | |||
25 | QTCOMMERCIALCHART_USE_NAMESPACE |
|
28 | QTCOMMERCIALCHART_USE_NAMESPACE | |
26 |
|
29 | |||
27 | DataSource::DataSource(QObject *parent) : |
|
30 | DataSource::DataSource(QAbstractScrollArea *appViewer, QObject *parent) : | |
|
31 | m_appViewer(appViewer), | |||
28 | QObject(parent), |
|
32 | QObject(parent), | |
29 |
m_index( |
|
33 | m_index(-1) | |
30 | { |
|
34 | { | |
31 | const int rowCount = 5; |
|
35 | // generate | |
32 | const int colCount = 1024; |
|
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 | } | |||
33 |
|
52 | |||
|
53 | void DataSource::generateData(int type, int rowCount, int colCount) | |||
|
54 | { | |||
|
55 | qDebug() << "DataSource::generateData:" << type << rowCount << colCount; | |||
|
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 | for (int i(0); i < rowCount; i++) { |
|
63 | for (int i(0); i < rowCount; i++) { | |
35 | QList<QPointF> points; |
|
64 | QList<QPointF> points; | |
36 | for (int j(0); j < colCount; j++) { |
|
65 | for (int j(0); j < colCount; j++) { | |
37 |
qreal x |
|
66 | qreal x(0); | |
38 | qreal y = sin(3.14159265358979 / 50 * x) + 0.5 + (qreal) rand() / (qreal) RAND_MAX; |
|
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 | points.append(QPointF(x, y)); |
|
83 | points.append(QPointF(x, y)); | |
40 | } |
|
84 | } | |
41 | m_data.append(points); |
|
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); |
|
91 | if (enabled) | |
48 | Q_ASSERT(xySeries); |
|
92 | m_appViewer->setViewport(new QGLWidget()); | |
49 |
|
93 | else | ||
50 | QList<QPointF> points = m_data.at(m_index); |
|
94 | m_appViewer->setViewport(0); | |
51 | //xySeries->clear(); |
|
|||
52 | //xySeries->append(points); |
|
|||
53 | xySeries->replace(points); |
|
|||
54 | m_index = (m_index + 1) % m_data.count(); |
|
|||
55 | } |
|
95 | } |
@@ -24,20 +24,25 | |||||
24 | #include <QObject> |
|
24 | #include <QObject> | |
25 | #include <QAbstractSeries> |
|
25 | #include <QAbstractSeries> | |
26 |
|
26 | |||
|
27 | class QAbstractScrollArea; | |||
|
28 | ||||
27 | QTCOMMERCIALCHART_USE_NAMESPACE |
|
29 | QTCOMMERCIALCHART_USE_NAMESPACE | |
28 |
|
30 | |||
29 | class DataSource : public QObject |
|
31 | class DataSource : public QObject | |
30 | { |
|
32 | { | |
31 | Q_OBJECT |
|
33 | Q_OBJECT | |
32 | public: |
|
34 | public: | |
33 | explicit DataSource(QObject *parent = 0); |
|
35 | explicit DataSource(QAbstractScrollArea *appViewer, QObject *parent = 0); | |
34 |
|
36 | |||
35 | signals: |
|
37 | signals: | |
36 |
|
38 | |||
37 | public slots: |
|
39 | public slots: | |
|
40 | void generateData(int type, int rowCount, int colCount); | |||
38 | void update(QAbstractSeries *series); |
|
41 | void update(QAbstractSeries *series); | |
|
42 | void setOpenGL(bool enabled); | |||
39 |
|
43 | |||
40 | private: |
|
44 | private: | |
|
45 | QAbstractScrollArea *m_appViewer; | |||
41 | QList<QList<QPointF> > m_data; |
|
46 | QList<QList<QPointF> > m_data; | |
42 | int m_index; |
|
47 | int m_index; | |
43 | }; |
|
48 | }; |
@@ -21,7 +21,6 | |||||
21 | #include <QtGui/QApplication> |
|
21 | #include <QtGui/QApplication> | |
22 | #include <QDeclarativeEngine> |
|
22 | #include <QDeclarativeEngine> | |
23 | #include <QDeclarativeContext> |
|
23 | #include <QDeclarativeContext> | |
24 | #include <QGLWidget> |
|
|||
25 | #include "qmlapplicationviewer.h" |
|
24 | #include "qmlapplicationviewer.h" | |
26 | #include "datasource.h" |
|
25 | #include "datasource.h" | |
27 |
|
26 | |||
@@ -30,12 +29,11 Q_DECL_EXPORT int main(int argc, char *argv[]) | |||||
30 | QScopedPointer<QApplication> app(createApplication(argc, argv)); |
|
29 | QScopedPointer<QApplication> app(createApplication(argc, argv)); | |
31 | QScopedPointer<QmlApplicationViewer> viewer(QmlApplicationViewer::create()); |
|
30 | QScopedPointer<QmlApplicationViewer> viewer(QmlApplicationViewer::create()); | |
32 |
|
31 | |||
33 | DataSource dataSource; |
|
32 | DataSource dataSource(viewer.data()); | |
34 | viewer->rootContext()->setContextProperty("dataSource", &dataSource); |
|
33 | viewer->rootContext()->setContextProperty("dataSource", &dataSource); | |
35 |
|
34 | |||
36 | viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto); |
|
35 | viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto); | |
37 | viewer->setSource(QUrl("qrc:/qml/qmloscilloscope/main.qml")); |
|
36 | viewer->setSource(QUrl("qrc:/qml/qmloscilloscope/main.qml")); | |
38 | viewer->setViewport(new QGLWidget()); |
|
|||
39 | viewer->showExpanded(); |
|
37 | viewer->showExpanded(); | |
40 |
|
38 | |||
41 | return app->exec(); |
|
39 | return app->exec(); |
@@ -19,54 +19,38 | |||||
19 | ****************************************************************************/ |
|
19 | ****************************************************************************/ | |
20 |
|
20 | |||
21 | import QtQuick 1.0 |
|
21 | import QtQuick 1.0 | |
22 | import QtCommercial.Chart 1.0 |
|
|||
23 |
|
22 | |||
24 | Rectangle { |
|
23 | Rectangle { | |
|
24 | id: main | |||
25 | width: 400 |
|
25 | width: 400 | |
26 | height: 300 |
|
26 | height: 300 | |
27 |
|
27 | |||
28 | ChartView { |
|
28 | ControlPanel { | |
29 |
id: c |
|
29 | id: controlPanel | |
30 |
anchors. |
|
30 | anchors.top: parent.top | |
31 | title: "Oscilloscope" |
|
31 | anchors.topMargin: 10 | |
32 | animationOptions: ChartView.NoAnimation |
|
32 | anchors.bottom: parent.bottom | |
33 |
|
33 | anchors.left: parent.left | ||
34 | ValuesAxis { |
|
34 | anchors.leftMargin: 10 | |
35 | id: axisY |
|
35 | ||
36 | min: -1 |
|
36 | onSignalSourceChanged: { | |
37 | max: 3 |
|
37 | if (source == "sin") | |
38 | } |
|
38 | dataSource.generateData(0, signalCount, sampleCount); | |
39 |
|
39 | else | ||
40 | ValuesAxis { |
|
40 | dataSource.generateData(1, signalCount, sampleCount); | |
41 | id: axisX |
|
41 | } | |
42 | min: 0 |
|
42 | onOpenGLEnabled: dataSource.setOpenGL(enabled); | |
43 | max: 1000 |
|
43 | onAnimationsEnabled: scopeView.setAnimations(enabled); | |
44 | } |
|
44 | onSeriesTypeChanged: scopeView.changeSeriesType(type); | |
45 |
|
45 | onRefreshRateChanged: scopeView.changeRefreshRate(rate); | ||
46 | LineSeries { |
|
46 | } | |
47 | id: lineSeries1 |
|
47 | ||
48 | name: "signal 1" |
|
48 | ScopeView { | |
49 | } |
|
49 | id: scopeView | |
50 | LineSeries { |
|
50 | anchors.top: parent.top | |
51 | id: lineSeries2 |
|
51 | anchors.bottom: parent.bottom | |
52 | name: "signal 2" |
|
52 | anchors.right: parent.right | |
53 | } |
|
53 | anchors.left: controlPanel.right | |
54 | } |
|
54 | height: main.height | |
55 |
|
||||
56 | Timer { |
|
|||
57 | interval: 16 // 60 Hz |
|
|||
58 | running: true |
|
|||
59 | repeat: true |
|
|||
60 | onTriggered: { |
|
|||
61 | dataSource.update(lineSeries1); |
|
|||
62 | dataSource.update(lineSeries2); |
|
|||
63 | } |
|
|||
64 | } |
|
|||
65 |
|
||||
66 | Component.onCompleted: { |
|
|||
67 | chartView.setAxisX(axisX, lineSeries1); |
|
|||
68 | chartView.setAxisY(axisY, lineSeries1); |
|
|||
69 | chartView.setAxisX(axisX, lineSeries2); |
|
|||
70 | chartView.setAxisY(axisY, lineSeries2); |
|
|||
71 | } |
|
55 | } | |
72 | } |
|
56 | } |
@@ -1,5 +1,8 | |||||
1 | <RCC> |
|
1 | <RCC> | |
2 | <qresource prefix="/"> |
|
2 | <qresource prefix="/"> | |
3 | <file>qml/qmloscilloscope/main.qml</file> |
|
3 | <file>qml/qmloscilloscope/main.qml</file> | |
|
4 | <file>qml/qmloscilloscope/ControlPanel.qml</file> | |||
|
5 | <file>qml/qmloscilloscope/ScopeView.qml</file> | |||
|
6 | <file>qml/qmloscilloscope/MultiButton.qml</file> | |||
4 | </qresource> |
|
7 | </qresource> | |
5 | </RCC> |
|
8 | </RCC> |
General Comments 0
You need to be logged in to leave comments.
Login now