├── qml.qrc
├── qtquickcontrols2.conf
├── README.md
├── PlotView.qml
├── plotdata.cpp
├── plotdata.h
├── main.cpp
├── .gitignore
├── main.qml
├── qwtquick2.h
├── qwtquick2.pro
├── LICENSE
├── qwtquick2.cpp
└── qwtquick2.pro.user
/qml.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | main.qml
4 | qtquickcontrols2.conf
5 | PlotView.qml
6 |
7 |
8 |
--------------------------------------------------------------------------------
/qtquickcontrols2.conf:
--------------------------------------------------------------------------------
1 | ; This file can be edited to change the style of the application
2 | ; See Styling Qt Quick Controls 2 in the documentation for details:
3 | ; http://doc.qt.io/qt-5/qtquickcontrols2-styles.html
4 |
5 | [Controls]
6 | Style=Material
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # qwtquick2
2 |
3 | This is a wrapper to Qwt to render by QtQuick2. Inspired by [qmlplot](https://github.com/mosolovsa/qmlplot) (same thing using QCustomPlot)
4 |
5 | The plot it self is implemented in c++ but can be shown in qml.
6 |
7 | Requirements:
8 |
9 | - Qt 5.x (tested with 5.11)
10 | - Qwt (tested with 6.x)
11 |
--------------------------------------------------------------------------------
/PlotView.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.0
2 | import QwtQuick2 1.0
3 |
4 | Item {
5 | id: plotForm
6 |
7 | Text {
8 | id: text
9 | text: qsTr("Plot form")
10 | }
11 |
12 | QwtQuick2Plot {
13 | id: qwtPlot
14 | anchors.fill: parent
15 |
16 | Component.onCompleted: initQwtPlot()
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/plotdata.cpp:
--------------------------------------------------------------------------------
1 | #include "plotdata.h"
2 |
3 | PlotData::PlotData(const QVector *container) :
4 | _container(container)
5 | {
6 | }
7 |
8 | size_t PlotData::size() const
9 | {
10 | return static_cast(_container->size());
11 | }
12 |
13 | QPointF PlotData::sample(size_t i) const
14 | {
15 | return _container->at(static_cast(i));
16 | }
17 |
18 | QRectF PlotData::boundingRect() const
19 | {
20 | return qwtBoundingRect(*this);
21 | }
22 |
--------------------------------------------------------------------------------
/plotdata.h:
--------------------------------------------------------------------------------
1 | #ifndef PLOTDATA_H
2 | #define PLOTDATA_H
3 |
4 | #include
5 | #include
6 |
7 | #include
8 |
9 |
10 | class PlotData : public QwtSeriesData
11 | {
12 | public:
13 | PlotData(const QVector *container);
14 |
15 | private:
16 | const QVector* _container;
17 |
18 | // QwtSeriesData interface
19 | public:
20 | size_t size() const;
21 | QPointF sample(size_t i) const;
22 | QRectF boundingRect() const;
23 | };
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | #endif // PLOTDATA_H
33 |
--------------------------------------------------------------------------------
/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | //#include
3 | #include
4 | #include
5 |
6 | #include "qwtquick2.h"
7 |
8 | int main(int argc, char *argv[])
9 | {
10 | QApplication a(argc, argv);
11 | // QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
12 | // QGuiApplication app(argc, argv);
13 |
14 | qmlRegisterType("QwtQuick2", 1, 0, "QwtQuick2Plot");
15 |
16 | QQmlApplicationEngine engine;
17 | engine.load(QUrl(QLatin1String("qrc:/main.qml")));
18 |
19 | return a.exec();
20 | }
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # C++ objects and libs
2 | *.slo
3 | *.lo
4 | *.o
5 | *.a
6 | *.la
7 | *.lai
8 | *.so
9 | *.dll
10 | *.dylib
11 |
12 | # Qt-es
13 | object_script.*.Release
14 | object_script.*.Debug
15 | *_plugin_import.cpp
16 | /.qmake.cache
17 | /.qmake.stash
18 | *.pro.user
19 | *.pro.user.*
20 | *.qbs.user
21 | *.qbs.user.*
22 | *.moc
23 | moc_*.cpp
24 | moc_*.h
25 | qrc_*.cpp
26 | ui_*.h
27 | *.qmlc
28 | *.jsc
29 | Makefile*
30 | *build-*
31 |
32 | # Qt unit tests
33 | target_wrapper.*
34 |
35 | # QtCreator
36 | *.autosave
37 |
38 | # QtCreator Qml
39 | *.qmlproject.user
40 | *.qmlproject.user.*
41 |
42 | # QtCreator CMake
43 | CMakeLists.txt.user*
44 |
--------------------------------------------------------------------------------
/main.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.7
2 | import QtQuick.Controls 2.0
3 | import QtQuick.Layouts 1.0
4 |
5 | ApplicationWindow {
6 | visible: true
7 | width: 640
8 | height: 480
9 | title: qsTr("Hello QWT in QML")
10 |
11 | // Item {
12 | // id: mainView
13 | // anchors.fill: parent
14 | // PlotView {
15 | // }
16 | // }
17 | SwipeView {
18 | id: swipeView
19 | anchors.fill: parent
20 | currentIndex: tabBar.currentIndex
21 | interactive: false
22 |
23 | PlotView {
24 | }
25 |
26 | Page {
27 | Label {
28 | text: qsTr("Adding random data on 500 ms tick to plot")
29 | anchors.centerIn: parent
30 | }
31 | }
32 | }
33 |
34 | footer: TabBar {
35 | id: tabBar
36 | currentIndex: swipeView.currentIndex
37 | TabButton {
38 | text: qsTr("Plot")
39 | }
40 | TabButton {
41 | text: qsTr("Info")
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/qwtquick2.h:
--------------------------------------------------------------------------------
1 | #ifndef QMLPLOT_H
2 | #define QMLPLOT_H
3 |
4 | #include
5 |
6 | #include
7 | #include
8 |
9 | class QwtQuick2Plot : public QQuickPaintedItem
10 | {
11 | Q_OBJECT
12 |
13 | public:
14 | QwtQuick2Plot(QQuickItem* parent = nullptr);
15 | virtual ~QwtQuick2Plot();
16 |
17 | void paint(QPainter* painter);
18 |
19 | Q_INVOKABLE void initQwtPlot();
20 |
21 | protected:
22 | void routeMouseEvents(QMouseEvent* event);
23 | void routeWheelEvents(QWheelEvent* event);
24 |
25 | virtual void mousePressEvent(QMouseEvent* event);
26 | virtual void mouseReleaseEvent(QMouseEvent* event);
27 | virtual void mouseMoveEvent(QMouseEvent* event);
28 | virtual void mouseDoubleClickEvent(QMouseEvent* event);
29 | virtual void wheelEvent(QWheelEvent *event);
30 |
31 | virtual void timerEvent(QTimerEvent *event);
32 |
33 | private:
34 | QwtPlot* m_qwtPlot;
35 | QwtPlotCurve* m_curve1;
36 | QVector m_curve1_data;
37 | int m_timerId;
38 |
39 | void replotAndUpdate();
40 |
41 | private slots:
42 | void updatePlotSize();
43 |
44 | };
45 |
46 | #endif // QMLPLOT_H
47 |
--------------------------------------------------------------------------------
/qwtquick2.pro:
--------------------------------------------------------------------------------
1 | QT += qml quick core gui printsupport
2 |
3 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
4 |
5 | CONFIG += c++11
6 | CONFIG += qwt
7 |
8 | SOURCES += main.cpp \
9 | qwtquick2.cpp \
10 | plotdata.cpp
11 |
12 | RESOURCES += qml.qrc
13 |
14 | # Additional import path used to resolve QML modules in Qt Creators code model
15 | QML_IMPORT_PATH =
16 |
17 | # Additional import path used to resolve QML modules just for Qt Quick Designer
18 | QML_DESIGNER_IMPORT_PATH =
19 |
20 | # The following define makes your compiler emit warnings if you use
21 | # any feature of Qt which as been marked deprecated (the exact warnings
22 | # depend on your compiler). Please consult the documentation of the
23 | # deprecated API in order to know how to port your code away from it.
24 | DEFINES += QT_DEPRECATED_WARNINGS
25 |
26 | # You can also make your code fail to compile if you use deprecated APIs.
27 | # In order to do so, uncomment the following line.
28 | # You can also select to disable deprecated APIs only up to a certain version of Qt.
29 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
30 |
31 | HEADERS += \
32 | qwtquick2.h \
33 | plotdata.h
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | This is free and unencumbered software released into the public domain.
2 |
3 | Anyone is free to copy, modify, publish, use, compile, sell, or
4 | distribute this software, either in source code form or as a compiled
5 | binary, for any purpose, commercial or non-commercial, and by any
6 | means.
7 |
8 | In jurisdictions that recognize copyright laws, the author or authors
9 | of this software dedicate any and all copyright interest in the
10 | software to the public domain. We make this dedication for the benefit
11 | of the public at large and to the detriment of our heirs and
12 | successors. We intend this dedication to be an overt act of
13 | relinquishment in perpetuity of all present and future rights to this
14 | software under copyright law.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
24 | For more information, please refer to
25 |
--------------------------------------------------------------------------------
/qwtquick2.cpp:
--------------------------------------------------------------------------------
1 | #include "plotdata.h"
2 | #include "qwtquick2.h"
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #include
9 |
10 | QwtQuick2Plot::QwtQuick2Plot(QQuickItem* parent) : QQuickPaintedItem(parent)
11 | , m_qwtPlot(nullptr), m_timerId(0)
12 | {
13 | setFlag(QQuickItem::ItemHasContents, true);
14 | setAcceptedMouseButtons(Qt::AllButtons);
15 |
16 | connect(this, &QQuickPaintedItem::widthChanged, this, &QwtQuick2Plot::updatePlotSize);
17 | connect(this, &QQuickPaintedItem::heightChanged, this, &QwtQuick2Plot::updatePlotSize);
18 | }
19 |
20 | QwtQuick2Plot::~QwtQuick2Plot()
21 | {
22 | delete m_qwtPlot;
23 | m_qwtPlot = nullptr;
24 |
25 | if (m_timerId != 0) {
26 | killTimer(m_timerId);
27 | }
28 | }
29 |
30 | void QwtQuick2Plot::replotAndUpdate()
31 | {
32 | m_qwtPlot->replot();
33 | update();
34 | }
35 |
36 | void QwtQuick2Plot::initQwtPlot()
37 | {
38 | m_qwtPlot = new QwtPlot();
39 | // after replot() we need to call update() - so disable auto replot
40 | m_qwtPlot->setAutoReplot(false);
41 | m_qwtPlot->setStyleSheet("background: white");
42 |
43 | updatePlotSize();
44 |
45 | m_curve1 = new QwtPlotCurve("Curve 1");
46 |
47 | m_curve1->setPen(QPen(Qt::red));
48 | m_curve1->setStyle(QwtPlotCurve::Lines);
49 | m_curve1->setRenderHint(QwtPlotItem::RenderAntialiased);
50 |
51 | m_curve1->setData(new PlotData(&m_curve1_data));
52 |
53 | m_qwtPlot->setAxisTitle(m_qwtPlot->xBottom, tr("t"));
54 | m_qwtPlot->setAxisTitle(m_qwtPlot->yLeft, tr("S"));
55 |
56 | m_curve1->attach(m_qwtPlot);
57 |
58 | startTimer(500);
59 |
60 | replotAndUpdate();
61 | }
62 |
63 |
64 | void QwtQuick2Plot::paint(QPainter* painter)
65 | {
66 | if (m_qwtPlot) {
67 | QPixmap picture(boundingRect().size().toSize());
68 |
69 | QwtPlotRenderer renderer;
70 | renderer.renderTo(m_qwtPlot, picture);
71 |
72 | painter->drawPixmap(QPoint(), picture);
73 | }
74 | }
75 |
76 | void QwtQuick2Plot::mousePressEvent(QMouseEvent* event)
77 | {
78 | qDebug() << Q_FUNC_INFO;
79 | routeMouseEvents(event);
80 | }
81 |
82 | void QwtQuick2Plot::mouseReleaseEvent(QMouseEvent* event)
83 | {
84 | qDebug() << Q_FUNC_INFO;
85 | routeMouseEvents(event);
86 | }
87 |
88 | void QwtQuick2Plot::mouseMoveEvent(QMouseEvent* event)
89 | {
90 | routeMouseEvents(event);
91 | }
92 |
93 | void QwtQuick2Plot::mouseDoubleClickEvent(QMouseEvent* event)
94 | {
95 | qDebug() << Q_FUNC_INFO;
96 | routeMouseEvents(event);
97 | }
98 |
99 | void QwtQuick2Plot::wheelEvent(QWheelEvent* event)
100 | {
101 | routeWheelEvents(event);
102 | }
103 |
104 | void QwtQuick2Plot::timerEvent(QTimerEvent* /*event*/)
105 | {
106 | static double t, U;
107 | U = (static_cast(qrand()) / RAND_MAX) * 5;
108 |
109 | m_curve1_data.append(QPointF(t, U));
110 |
111 | qDebug() << Q_FUNC_INFO << QString("Adding dot t = %1, S = %2").arg(t).arg(U);
112 | t++;
113 | replotAndUpdate();
114 | }
115 |
116 | void QwtQuick2Plot::routeMouseEvents(QMouseEvent* event)
117 | {
118 | if (m_qwtPlot) {
119 | QMouseEvent* newEvent = new QMouseEvent(event->type(), event->localPos(),
120 | event->button(), event->buttons(),
121 | event->modifiers());
122 | QCoreApplication::postEvent(m_qwtPlot, newEvent);
123 | }
124 | }
125 |
126 | void QwtQuick2Plot::routeWheelEvents(QWheelEvent* event)
127 | {
128 | if (m_qwtPlot) {
129 | QWheelEvent* newEvent = new QWheelEvent(event->pos(), event->delta(),
130 | event->buttons(), event->modifiers(),
131 | event->orientation());
132 | QCoreApplication::postEvent(m_qwtPlot, newEvent);
133 | }
134 | }
135 |
136 | void QwtQuick2Plot::updatePlotSize()
137 | {
138 | if (m_qwtPlot) {
139 | m_qwtPlot->setGeometry(0, 0, static_cast(width()), static_cast(height()));
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/qwtquick2.pro.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | EnvironmentId
7 | {864aab5c-03ce-4e72-b615-2f53bd11c95a}
8 |
9 |
10 | ProjectExplorer.Project.ActiveTarget
11 | 0
12 |
13 |
14 | ProjectExplorer.Project.EditorSettings
15 |
16 | true
17 | false
18 | true
19 |
20 | Cpp
21 |
22 | CppGlobal
23 |
24 |
25 |
26 | QmlJS
27 |
28 | QmlJSGlobal
29 |
30 |
31 | 2
32 | UTF-8
33 | false
34 | 4
35 | false
36 | 80
37 | true
38 | true
39 | 1
40 | true
41 | false
42 | 0
43 | true
44 | true
45 | 0
46 | 8
47 | true
48 | 1
49 | true
50 | true
51 | true
52 | false
53 |
54 |
55 |
56 | ProjectExplorer.Project.PluginSettings
57 |
58 |
59 | true
60 |
61 |
62 |
63 | ProjectExplorer.Project.Target.0
64 |
65 | Desktop
66 | Desktop
67 | {b8c177b3-2345-4c44-8408-2b94c0cdee8e}
68 | 0
69 | 0
70 | 0
71 |
72 | /home/loeppel/Devel/microtap/build-qwt-quickpainted-Desktop-Debug
73 |
74 |
75 | true
76 | qmake
77 |
78 | QtProjectManager.QMakeBuildStep
79 | true
80 |
81 | false
82 | false
83 | false
84 |
85 |
86 | true
87 | Make
88 |
89 | Qt4ProjectManager.MakeStep
90 |
91 | -w
92 | -r
93 |
94 | false
95 |
96 |
97 |
98 | 2
99 | Erstellen
100 |
101 | ProjectExplorer.BuildSteps.Build
102 |
103 |
104 |
105 | true
106 | Make
107 |
108 | Qt4ProjectManager.MakeStep
109 |
110 | -w
111 | -r
112 |
113 | true
114 | clean
115 |
116 |
117 | 1
118 | Bereinigen
119 |
120 | ProjectExplorer.BuildSteps.Clean
121 |
122 | 2
123 | false
124 |
125 | Debug
126 | Debug
127 | Qt4ProjectManager.Qt4BuildConfiguration
128 | 2
129 | true
130 |
131 |
132 | /home/loeppel/Devel/microtap/build-qwt-quickpainted-Desktop-Release
133 |
134 |
135 | true
136 | qmake
137 |
138 | QtProjectManager.QMakeBuildStep
139 | false
140 |
141 | false
142 | false
143 | true
144 |
145 |
146 | true
147 | Make
148 |
149 | Qt4ProjectManager.MakeStep
150 |
151 | -w
152 | -r
153 |
154 | false
155 |
156 |
157 |
158 | 2
159 | Erstellen
160 |
161 | ProjectExplorer.BuildSteps.Build
162 |
163 |
164 |
165 | true
166 | Make
167 |
168 | Qt4ProjectManager.MakeStep
169 |
170 | -w
171 | -r
172 |
173 | true
174 | clean
175 |
176 |
177 | 1
178 | Bereinigen
179 |
180 | ProjectExplorer.BuildSteps.Clean
181 |
182 | 2
183 | false
184 |
185 | Release
186 | Release
187 | Qt4ProjectManager.Qt4BuildConfiguration
188 | 0
189 | true
190 |
191 |
192 | /home/loeppel/Devel/microtap/build-qwt-quickpainted-Desktop-Profile
193 |
194 |
195 | true
196 | qmake
197 |
198 | QtProjectManager.QMakeBuildStep
199 | true
200 |
201 | false
202 | true
203 | true
204 |
205 |
206 | true
207 | Make
208 |
209 | Qt4ProjectManager.MakeStep
210 |
211 | -w
212 | -r
213 |
214 | false
215 |
216 |
217 |
218 | 2
219 | Erstellen
220 |
221 | ProjectExplorer.BuildSteps.Build
222 |
223 |
224 |
225 | true
226 | Make
227 |
228 | Qt4ProjectManager.MakeStep
229 |
230 | -w
231 | -r
232 |
233 | true
234 | clean
235 |
236 |
237 | 1
238 | Bereinigen
239 |
240 | ProjectExplorer.BuildSteps.Clean
241 |
242 | 2
243 | false
244 |
245 | Profile
246 | Profile
247 | Qt4ProjectManager.Qt4BuildConfiguration
248 | 0
249 | true
250 |
251 | 3
252 |
253 |
254 | 0
255 | Deployment
256 |
257 | ProjectExplorer.BuildSteps.Deploy
258 |
259 | 1
260 | Deployment-Konfiguration
261 |
262 | ProjectExplorer.DefaultDeployConfiguration
263 |
264 | 1
265 |
266 |
267 | false
268 | false
269 | 1000
270 |
271 | true
272 |
273 | false
274 | false
275 | false
276 | false
277 | true
278 | 0.01
279 | 10
280 | true
281 | 1
282 | 25
283 |
284 | 1
285 | true
286 | false
287 | true
288 | valgrind
289 |
290 | 0
291 | 1
292 | 2
293 | 3
294 | 4
295 | 5
296 | 6
297 | 7
298 | 8
299 | 9
300 | 10
301 | 11
302 | 12
303 | 13
304 | 14
305 |
306 | 2
307 |
308 | qwt-quickpainted
309 |
310 | Qt4ProjectManager.Qt4RunConfiguration:/home/loeppel/Devel/microtap/qwt-quickpainted/qwt-quickpainted.pro
311 | true
312 |
313 | qwt-quickpainted.pro
314 |
315 | /home/loeppel/Devel/microtap/build-qwt-quickpainted-Desktop-Debug
316 | 3768
317 | false
318 | true
319 | false
320 | false
321 | true
322 |
323 | 1
324 |
325 |
326 |
327 | ProjectExplorer.Project.TargetCount
328 | 1
329 |
330 |
331 | ProjectExplorer.Project.Updater.FileVersion
332 | 18
333 |
334 |
335 | Version
336 | 18
337 |
338 |
339 |
--------------------------------------------------------------------------------