1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtSensors module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | #include "qsensor.h" |
41 | #include "qsensor_p.h" |
42 | #include "qsensorbackend.h" |
43 | #include "qsensormanager.h" |
44 | #include <QDebug> |
45 | #include <QMetaProperty> |
46 | #include <QTimer> |
47 | |
48 | QT_BEGIN_NAMESPACE |
49 | |
50 | /*! |
51 | \typedef qrange |
52 | \relates QSensor |
53 | \since 5.1 |
54 | |
55 | This type is defined as a QPair. |
56 | |
57 | \code |
58 | typedef QPair<int,int> qrange; |
59 | \endcode |
60 | |
61 | \sa QPair, qrangelist, QSensor::availableDataRates |
62 | */ |
63 | |
64 | /*! |
65 | \typedef qrangelist |
66 | \relates QSensor |
67 | \since 5.1 |
68 | |
69 | This type is defined as a list of qrange values. |
70 | |
71 | \code |
72 | typedef QList<qrange> qrangelist; |
73 | \endcode |
74 | |
75 | \sa QList, qrange, QSensor::availableDataRates |
76 | */ |
77 | |
78 | /*! |
79 | \class qoutputrange |
80 | \inmodule QtSensors |
81 | \brief The qoutputrange class holds the specifics of an output range. |
82 | \since 5.1 |
83 | |
84 | The class is defined as a simple struct. |
85 | |
86 | \code |
87 | struct qoutputrange |
88 | { |
89 | qreal maximum; |
90 | qreal minimum; |
91 | qreal accuracy; |
92 | }; |
93 | \endcode |
94 | |
95 | Each output range specifies a minimum and maximum value as well as an accuracy value. |
96 | The accuracy value represents the resolution of the sensor. It is the smallest change |
97 | the sensor can detect and is expressed using the same units as the minimum and maximum. |
98 | |
99 | Sensors must often trade off range for accuracy. To allow the user to determine which of |
100 | these are more important the sensor may offer several output ranges. One output |
101 | range may have reduced minimum and maximum values and increased sensitivity. Another output |
102 | range may have higher minimum and maximum values with reduced sensitivity. Note that higher |
103 | sensitivities will be represented by smaller accuracy values. |
104 | |
105 | An example of this tradeoff can be seen by examining the LIS302DL accelerometer. It has only |
106 | 256 possible values to report with. These values are scaled so that they can represent either |
107 | -2G to +2G (with an accuracy value of 0.015G) or -8G to +8G (with an accuracy value of 0.06G). |
108 | |
109 | \sa qoutputrangelist, QSensor::outputRanges |
110 | */ |
111 | |
112 | /*! |
113 | \variable qoutputrange::maximum |
114 | |
115 | This is the maximum value for this output range. |
116 | The units are defined by the sensor. |
117 | */ |
118 | |
119 | /*! |
120 | \variable qoutputrange::minimum |
121 | |
122 | This is the minimum value for this output range. |
123 | The units are defined by the sensor. |
124 | */ |
125 | |
126 | /*! |
127 | \variable qoutputrange::accuracy |
128 | |
129 | The accuracy value represents the resolution of the sensor. It is the smallest change |
130 | the sensor can detect and is expressed using the same units as the minimum and maximum. |
131 | */ |
132 | |
133 | /*! |
134 | \typedef qoutputrangelist |
135 | \relates QSensor |
136 | \since 5.1 |
137 | |
138 | This type is defined as a list of qoutputrange values. |
139 | |
140 | \code |
141 | typedef QList<qoutputrange> qoutputrangelist; |
142 | \endcode |
143 | |
144 | \sa QList, qoutputrange, QSensor::outputRanges |
145 | */ |
146 | |
147 | static void registerTypes() |
148 | { |
149 | qRegisterMetaType<qrange>(typeName: "qrange" ); |
150 | qRegisterMetaType<qrangelist>(typeName: "qrangelist" ); |
151 | qRegisterMetaType<qoutputrangelist>(typeName: "qoutputrangelist" ); |
152 | } |
153 | Q_CONSTRUCTOR_FUNCTION(registerTypes) |
154 | |
155 | // ===================================================================== |
156 | |
157 | void QSensorPrivate::init(const QByteArray &sensorType) |
158 | { |
159 | Q_Q(QSensor); |
160 | type = sensorType; |
161 | q->registerInstance(); // so the availableSensorsChanged() signal works |
162 | } |
163 | |
164 | /*! |
165 | \class QSensor |
166 | \ingroup sensors_main |
167 | \inmodule QtSensors |
168 | \since 5.1 |
169 | |
170 | \brief The QSensor class represents a single hardware sensor. |
171 | |
172 | The life cycle of a sensor is typically: |
173 | |
174 | \list |
175 | \li Create a sub-class of QSensor on the stack or heap. |
176 | \li Setup as required by the application. |
177 | \li Start receiving values. |
178 | \li Sensor data is used by the application. |
179 | \li Stop receiving values. |
180 | \endlist |
181 | |
182 | The sensor data is delivered via QSensorReading and its sub-classes. |
183 | |
184 | \section1 Orientation |
185 | |
186 | Some sensors react to screen orientation changes, such as QAccelerometer, QMagnetometer and |
187 | QRotationSensor. These are so called \e orientable sensors. For orientable sensors, |
188 | QSensor supports changing the reporting of the reading values based on the orientation of the |
189 | screen. |
190 | |
191 | For orientable sensors, the axesOrientationMode property controls how the orientation affects |
192 | the reading values. |
193 | |
194 | In the default mode, QSensor::FixedOrientation, the reading values remain |
195 | unaffected by the orientation. In the QSensor::AutomaticOrientation mode, the reading |
196 | values are automatically rotated by taking the current screen orientation into account. And |
197 | finally, in the QSensor::UserOrientation mode, the reading values are rotated |
198 | according to a user-specified orientation. |
199 | |
200 | The functionality of this is only available if it is supported by the backend and if the sensor |
201 | is orientable, which can be checked by calling QSensor::isFeatureSupported() |
202 | with the QSensor::AxesOrientation flag. |
203 | |
204 | The orientation values here are always of the screen orientation, not the device orientation. |
205 | The screen orientation is the orientation of the GUI. For example when rotating a device by 90 |
206 | degrees counter-clockwise, the screen orientation compensates for that by rotating 90 degrees |
207 | clockwise, to the effect that the GUI is still facing upright after the device has been rotated. |
208 | Note that applications can lock the screen orientation, for example to force portrait or landscape |
209 | mode. For locked orientations, orientable sensors will not react with reading changes if the device |
210 | orientation is changed, as orientable sensors react to screen orientation changes only. This makes |
211 | sense, as the purpose of orientable sensors is to keep the sensor orientation in sync with the screen |
212 | orientation. |
213 | |
214 | The orientation values range from 0 to 270 degrees. The orientation is applied in clockwise direction, |
215 | e.g. an orientation value of 90 degrees means that the screen has been rotated 90 degress to the right |
216 | from its origin position, to compensate a device rotation of 90 degrees to the left. |
217 | |
218 | \sa QSensorReading |
219 | */ |
220 | |
221 | /*! |
222 | \enum QSensor::Feature |
223 | \brief Lists optional features a backend might support. |
224 | |
225 | The features common to all sensor types are: |
226 | |
227 | \value Buffering The backend supports buffering of readings, controlled by the |
228 | QSensor::bufferSize property. |
229 | \value AlwaysOn The backend supports changing the policy on whether to suspend when idle, |
230 | controlled by the QSensor::alwaysOn property. |
231 | \value SkipDuplicates The backend supports skipping of same or very similar successive |
232 | readings. This can be enabled by setting the QSensor::skipDuplicates |
233 | property to true. |
234 | |
235 | The features of QMagnetometer are: |
236 | |
237 | \value GeoValues The backend supports returning geo values, which can be |
238 | controlled with the QMagnetometer::returnGeoValues property. |
239 | |
240 | The features of QLightSensor are: |
241 | |
242 | \value FieldOfView The backend specifies its field of view, which can be |
243 | read from the QLightSensor::fieldOfView property. |
244 | |
245 | The features of QAccelerometer are: |
246 | |
247 | \value AccelerationMode The backend supports switching the acceleration mode |
248 | of the acceleromter with the QAccelerometer::accelerationMode property. |
249 | |
250 | The features of QPressureSensor are: |
251 | |
252 | \value PressureSensorTemperature The backend provides the pressure sensor's die temperature |
253 | |
254 | The features of all orientable sensors are: |
255 | |
256 | \value AxesOrientation The backend supports changing the axes orientation from the default of |
257 | QSensor::FixedOrientation to something else. |
258 | |
259 | \omitvalue Reserved |
260 | |
261 | \sa QSensor::isFeatureSupported() |
262 | \since 5.0 |
263 | */ |
264 | |
265 | /*! |
266 | Construct the \a type sensor as a child of \a parent. |
267 | |
268 | Do not use this constructor if a derived class exists for the specific sensor type. |
269 | |
270 | The wrong way is to use the base class constructor: |
271 | \snippet sensors/creating.cpp 3 |
272 | The right way is to create an instance of the derived class: |
273 | \snippet sensors/creating.cpp 2 |
274 | |
275 | The derived classes have |
276 | additional properties and data members which are needed for certain features such as |
277 | geo value support in QMagnetometer or acceleration mode support in QAccelerometer. |
278 | These features will only work properly when creating a sensor instance from a QSensor |
279 | subclass. |
280 | |
281 | Only use this constructor if there is no derived sensor class available. Note that all |
282 | built-in sensors have a derived class, so using this constructor should only be necessary |
283 | when implementing custom sensors, like in the \l {Qt Sensors - Grue Sensor Example}{Grue sensor example}. |
284 | */ |
285 | QSensor::QSensor(const QByteArray &type, QObject *parent) |
286 | : QObject(*new QSensorPrivate, parent) |
287 | { |
288 | Q_D(QSensor); |
289 | d->init(sensorType: type); |
290 | } |
291 | |
292 | /*! \internal |
293 | */ |
294 | QSensor::QSensor(const QByteArray &type, QSensorPrivate &dd, QObject* parent) |
295 | : QObject(dd, parent) |
296 | { |
297 | Q_D(QSensor); |
298 | d->init(sensorType: type); |
299 | } |
300 | |
301 | /*! \internal |
302 | */ |
303 | QSensorBackend *QSensor::backend() const |
304 | { |
305 | Q_D(const QSensor); |
306 | return d->backend; |
307 | } |
308 | |
309 | /*! |
310 | Destroy the sensor. Stops the sensor if it has not already been stopped. |
311 | */ |
312 | QSensor::~QSensor() |
313 | { |
314 | Q_D(QSensor); |
315 | stop(); |
316 | Q_FOREACH (QSensorFilter *filter, d->filters) |
317 | filter->setSensor(0); |
318 | delete d->backend; |
319 | d->backend = 0; |
320 | // owned by the backend |
321 | d->device_reading = 0; |
322 | d->filter_reading = 0; |
323 | d->cache_reading = 0; |
324 | } |
325 | |
326 | /*! |
327 | \property QSensor::connectedToBackend |
328 | \brief a value indicating if the sensor has connected to a backend. |
329 | |
330 | A sensor that has not been connected to a backend cannot do anything useful. |
331 | |
332 | Call the connectToBackend() method to force the sensor to connect to a backend |
333 | immediately. This is automatically called if you call start() so you only need |
334 | to do this if you need access to sensor properties (ie. to poll the sensor's |
335 | meta-data before you use it). |
336 | */ |
337 | |
338 | bool QSensor::isConnectedToBackend() const |
339 | { |
340 | Q_D(const QSensor); |
341 | return (d->backend != 0); |
342 | } |
343 | |
344 | /*! |
345 | \property QSensor::identifier |
346 | \brief the backend identifier for the sensor. |
347 | |
348 | Note that the identifier is filled out automatically |
349 | when the sensor is connected to a backend. If you want |
350 | to connect a specific backend, you should call |
351 | setIdentifier() before connectToBackend(). |
352 | */ |
353 | |
354 | QByteArray QSensor::identifier() const |
355 | { |
356 | Q_D(const QSensor); |
357 | return d->identifier; |
358 | } |
359 | |
360 | void QSensor::setIdentifier(const QByteArray &identifier) |
361 | { |
362 | Q_D(QSensor); |
363 | if (isConnectedToBackend()) { |
364 | qWarning() << "ERROR: Cannot call QSensor::setIdentifier while connected to a backend!" ; |
365 | return; |
366 | } |
367 | d->identifier = identifier; |
368 | } |
369 | |
370 | /*! |
371 | \property QSensor::type |
372 | \brief the type of the sensor. |
373 | */ |
374 | |
375 | QByteArray QSensor::type() const |
376 | { |
377 | Q_D(const QSensor); |
378 | return d->type; |
379 | } |
380 | |
381 | /*! |
382 | Try to connect to a sensor backend. |
383 | |
384 | Returns true if a suitable backend could be found, false otherwise. |
385 | |
386 | The type must be set before calling this method if you are using QSensor directly. |
387 | |
388 | \sa isConnectedToBackend() |
389 | */ |
390 | bool QSensor::connectToBackend() |
391 | { |
392 | Q_D(QSensor); |
393 | if (isConnectedToBackend()) |
394 | return true; |
395 | |
396 | int dataRate = d->dataRate; |
397 | int outputRange = d->outputRange; |
398 | |
399 | d->backend = QSensorManager::createBackend(sensor: this); |
400 | |
401 | if (d->backend) { |
402 | // Reset the properties to their default values and re-set them now so |
403 | // that the logic we've put into the setters gets called. |
404 | if (dataRate != 0) { |
405 | d->dataRate = 0; |
406 | setDataRate(dataRate); |
407 | } |
408 | if (outputRange != -1) { |
409 | d->outputRange = -1; |
410 | setOutputRange(outputRange); |
411 | } |
412 | } |
413 | |
414 | return isConnectedToBackend(); |
415 | } |
416 | |
417 | /*! |
418 | \property QSensor::busy |
419 | \brief a value to indicate if the sensor is busy. |
420 | |
421 | Some sensors may be on the system but unavailable for use. |
422 | This function will return true if the sensor is busy. You |
423 | will not be able to start() the sensor. |
424 | |
425 | Note that this function does not return true if you |
426 | are using the sensor, only if another process is using |
427 | the sensor. |
428 | |
429 | \sa busyChanged() |
430 | */ |
431 | |
432 | bool QSensor::isBusy() const |
433 | { |
434 | Q_D(const QSensor); |
435 | return d->busy; |
436 | } |
437 | |
438 | /*! |
439 | \fn QSensor::busyChanged() |
440 | |
441 | This signal is emitted when the sensor is no longer busy. |
442 | This can be used to grab a sensor when it becomes available. |
443 | |
444 | \code |
445 | sensor.start(); |
446 | if (sensor.isBusy()) { |
447 | // need to wait for busyChanged signal and try again |
448 | } |
449 | \endcode |
450 | */ |
451 | |
452 | /*! |
453 | \property QSensor::active |
454 | \brief a value to indicate if the sensor is active. |
455 | |
456 | This is true if the sensor is active (returning values). This is false otherwise. |
457 | |
458 | Note that setting this value to true will not have an immediate effect. Instead, |
459 | the sensor will be started once the event loop has been reached. |
460 | */ |
461 | void QSensor::setActive(bool active) |
462 | { |
463 | if (active == isActive()) |
464 | return; |
465 | |
466 | if (active) |
467 | QTimer::singleShot(msec: 0, receiver: this, SLOT(start())); // delay ensures all properties have been set if using QML |
468 | else |
469 | stop(); |
470 | } |
471 | |
472 | bool QSensor::isActive() const |
473 | { |
474 | Q_D(const QSensor); |
475 | return d->active; |
476 | } |
477 | |
478 | /*! |
479 | \property QSensor::alwaysOn |
480 | \brief a value to indicate if the sensor should remain running when the screen is off. |
481 | |
482 | Some platforms have a policy of suspending sensors when the screen turns off. |
483 | Setting this property to true will ensure the sensor continues to run. |
484 | */ |
485 | /*! |
486 | \fn QSensor::alwaysOnChanged() |
487 | |
488 | This signal is emitted when the alwaysOn property changes. |
489 | */ |
490 | void QSensor::setAlwaysOn(bool alwaysOn) |
491 | { |
492 | Q_D(QSensor); |
493 | if (d->alwaysOn == alwaysOn) return; |
494 | d->alwaysOn = alwaysOn; |
495 | emit alwaysOnChanged(); |
496 | } |
497 | |
498 | bool QSensor::isAlwaysOn() const |
499 | { |
500 | Q_D(const QSensor); |
501 | return d->alwaysOn; |
502 | } |
503 | |
504 | /*! |
505 | \property QSensor::skipDuplicates |
506 | \brief Indicates whether duplicate reading values should be omitted. |
507 | \since 5.1 |
508 | |
509 | When duplicate skipping is enabled, successive readings with the same or very |
510 | similar values are omitted. This helps reducing the amount of processing done, as less sensor |
511 | readings are made available. As a consequence, readings arrive at an irregular interval. |
512 | |
513 | Duplicate skipping is not just enabled for readings that are exactly the same, but also for |
514 | readings that are quite similar, as each sensor has a bit of jitter even if the device is |
515 | not moved. |
516 | |
517 | Support for this property depends on the backend. Use isFeatureSupported() to check if it is |
518 | supported on the current platform. |
519 | |
520 | Duplicate skipping is disabled by default. |
521 | |
522 | Duplicate skipping takes effect when the sensor is started, changing the property while the |
523 | sensor is active has no immediate effect. |
524 | */ |
525 | bool QSensor::skipDuplicates() const |
526 | { |
527 | Q_D(const QSensor); |
528 | return d->skipDuplicates; |
529 | } |
530 | |
531 | /*! |
532 | Sets the duplicate skipping to \a skipDuplicates. |
533 | |
534 | \since 5.1 |
535 | */ |
536 | void QSensor::setSkipDuplicates(bool skipDuplicates) |
537 | { |
538 | Q_D(QSensor); |
539 | if (d->skipDuplicates != skipDuplicates) { |
540 | d->skipDuplicates = skipDuplicates; |
541 | emit skipDuplicatesChanged(skipDuplicates); |
542 | } |
543 | } |
544 | |
545 | /*! |
546 | \fn QSensor::skipDuplicatesChanged(bool skipDuplicates) |
547 | \since 5.1 |
548 | |
549 | This signal is emitted when the \a skipDuplicates property changes. |
550 | */ |
551 | |
552 | /*! |
553 | \property QSensor::availableDataRates |
554 | \brief the data rates that the sensor supports. |
555 | |
556 | This is a list of the data rates that the sensor supports. |
557 | Measured in Hertz. |
558 | |
559 | Entries in the list can represent discrete rates or a |
560 | continuous range of rates. |
561 | A discrete rate is noted by having both values the same. |
562 | |
563 | See the sensor_explorer example for an example of how to interpret and use |
564 | this information. |
565 | |
566 | Note that this information is not mandatory as not all sensors have a rate at which |
567 | they run. In such cases, the list will be empty. |
568 | |
569 | \sa QSensor::dataRate, qrangelist |
570 | */ |
571 | |
572 | qrangelist QSensor::availableDataRates() const |
573 | { |
574 | Q_D(const QSensor); |
575 | return d->availableDataRates; |
576 | } |
577 | |
578 | /*! |
579 | \property QSensor::dataRate |
580 | \brief the data rate that the sensor should be run at. |
581 | |
582 | Measured in Hertz. |
583 | |
584 | The data rate is the maximum frequency at which the sensor can detect changes. |
585 | |
586 | Setting this property is not portable and can cause conflicts with other |
587 | applications. Check with the sensor backend and platform documentation for |
588 | any policy regarding multiple applications requesting a data rate. |
589 | |
590 | The default value (0) means that the app does not care what the data rate is. |
591 | Applications should consider using a timer-based poll of the current value or |
592 | ensure that the code that processes values can run very quickly as the platform |
593 | may provide updates hundreds of times each second. |
594 | |
595 | This should be set before calling start() because the sensor may not |
596 | notice changes to this value while it is running. |
597 | |
598 | Note that there is no mechanism to determine the current data rate in use by the |
599 | platform. |
600 | |
601 | \sa QSensor::availableDataRates |
602 | */ |
603 | |
604 | int QSensor::dataRate() const |
605 | { |
606 | Q_D(const QSensor); |
607 | return d->dataRate; |
608 | } |
609 | |
610 | void QSensor::setDataRate(int rate) |
611 | { |
612 | Q_D(QSensor); |
613 | if (d->dataRate != rate) { |
614 | d->dataRate = rate; |
615 | emit dataRateChanged(); |
616 | } |
617 | } |
618 | |
619 | /*! |
620 | Checks if a specific feature is supported by the backend. |
621 | |
622 | QtSensors supports a rich API for controlling and providing information about sensors. Naturally, |
623 | not all of this functionality can be supported by all of the backends. |
624 | |
625 | To check if the current backend supports the feature \a feature, call this function. |
626 | |
627 | The backend needs to be connected, otherwise false will be returned. Calling connectToBackend() |
628 | or start() will create a connection to the backend. |
629 | |
630 | Backends have to implement QSensorBackend::isFeatureSupported() to make this work. |
631 | |
632 | Returns whether or not the feature is supported if the backend is connected, or false if the backend is not connected. |
633 | \since 5.0 |
634 | */ |
635 | bool QSensor::isFeatureSupported(Feature feature) const |
636 | { |
637 | Q_D(const QSensor); |
638 | return d->backend && d->backend->isFeatureSupported(feature); |
639 | } |
640 | |
641 | /*! |
642 | Start retrieving values from the sensor. |
643 | Returns true if the sensor was started, false otherwise. |
644 | |
645 | The sensor may fail to start for several reasons. |
646 | |
647 | Once an application has started a sensor it must wait until the sensor receives a |
648 | new value before it can query the sensor's values. This is due to how the sensor |
649 | receives values from the system. Sensors do not (in general) poll for new values, |
650 | rather new values are pushed to the sensors as they happen. |
651 | |
652 | For example, this code will not work as intended. |
653 | |
654 | \badcode |
655 | sensor->start(); |
656 | sensor->reading()->x(); // no data available |
657 | \endcode |
658 | |
659 | To work correctly, the code that accesses the reading should ensure the |
660 | readingChanged() signal has been emitted. |
661 | |
662 | \code |
663 | connect(sensor, SIGNAL(readingChanged()), this, SLOT(checkReading())); |
664 | sensor->start(); |
665 | } |
666 | void MyClass::checkReading() { |
667 | sensor->reading()->x(); |
668 | \endcode |
669 | |
670 | \sa QSensor::busy |
671 | */ |
672 | bool QSensor::start() |
673 | { |
674 | Q_D(QSensor); |
675 | if (isActive()) |
676 | return true; |
677 | if (!connectToBackend()) |
678 | return false; |
679 | // Set these flags to their defaults |
680 | d->active = true; |
681 | d->busy = false; |
682 | // Backend will update the flags appropriately |
683 | d->backend->start(); |
684 | Q_EMIT activeChanged(); |
685 | return isActive(); |
686 | } |
687 | |
688 | /*! |
689 | Stop retrieving values from the sensor. |
690 | |
691 | This releases the sensor so that other processes can use it. |
692 | |
693 | \sa QSensor::busy |
694 | */ |
695 | void QSensor::stop() |
696 | { |
697 | Q_D(QSensor); |
698 | if (!isConnectedToBackend() || !isActive()) |
699 | return; |
700 | d->active = false; |
701 | d->backend->stop(); |
702 | Q_EMIT activeChanged(); |
703 | } |
704 | |
705 | /*! |
706 | \property QSensor::reading |
707 | \brief the reading class. |
708 | |
709 | The reading class provides access to sensor readings. The reading object |
710 | is a volatile cache of the most recent sensor reading that has been received |
711 | so the application should process readings immediately or save the values |
712 | somewhere for later processing. |
713 | |
714 | Note that this will return 0 until a sensor backend is connected to a backend. |
715 | |
716 | Also note that readings are not immediately available after start() is called. |
717 | Applications must wait for the readingChanged() signal to be emitted. |
718 | |
719 | \sa isConnectedToBackend(), start() |
720 | */ |
721 | |
722 | QSensorReading *QSensor::reading() const |
723 | { |
724 | Q_D(const QSensor); |
725 | return d->cache_reading; |
726 | } |
727 | |
728 | /*! |
729 | Add a \a filter to the sensor. |
730 | |
731 | The sensor does not take ownership of the filter. |
732 | QSensorFilter will inform the sensor if it is destroyed. |
733 | |
734 | \sa QSensorFilter |
735 | */ |
736 | void QSensor::addFilter(QSensorFilter *filter) |
737 | { |
738 | Q_D(QSensor); |
739 | if (!filter) { |
740 | qWarning() << "addFilter: passed a null filter!" ; |
741 | return; |
742 | } |
743 | filter->setSensor(this); |
744 | d->filters << filter; |
745 | } |
746 | |
747 | /*! |
748 | Remove \a filter from the sensor. |
749 | |
750 | \sa QSensorFilter |
751 | */ |
752 | void QSensor::removeFilter(QSensorFilter *filter) |
753 | { |
754 | Q_D(QSensor); |
755 | if (!filter) { |
756 | qWarning() << "removeFilter: passed a null filter!" ; |
757 | return; |
758 | } |
759 | d->filters.removeOne(t: filter); |
760 | filter->setSensor(0); |
761 | } |
762 | |
763 | /*! |
764 | Returns the filters currently attached to the sensor. |
765 | |
766 | \sa QSensorFilter |
767 | */ |
768 | QList<QSensorFilter*> QSensor::filters() const |
769 | { |
770 | Q_D(const QSensor); |
771 | return d->filters; |
772 | } |
773 | |
774 | /*! |
775 | \fn QSensor::readingChanged() |
776 | |
777 | This signal is emitted when a new sensor reading is received. |
778 | |
779 | The sensor reading can be found in the QSensor::reading property. Note that the |
780 | reading object is a volatile cache of the most recent sensor reading that has |
781 | been received so the application should process the reading immediately or |
782 | save the values somewhere for later processing. |
783 | |
784 | Before this signal has been emitted for the first time, the reading object will |
785 | have uninitialized data. |
786 | |
787 | \sa start() |
788 | */ |
789 | |
790 | /*! |
791 | \fn QSensor::activeChanged() |
792 | |
793 | This signal is emitted when the QSensor::active property has changed. |
794 | |
795 | \sa QSensor::active |
796 | */ |
797 | |
798 | /*! |
799 | \property QSensor::outputRanges |
800 | \brief a list of output ranges the sensor supports. |
801 | |
802 | A sensor may have more than one output range. Typically this is done |
803 | to give a greater measurement range at the cost of lowering accuracy. |
804 | |
805 | Note that this information is not mandatory. This information is typically only |
806 | available for sensors that have selectable output ranges (such as typical |
807 | accelerometers). |
808 | |
809 | \sa QSensor::outputRange, qoutputrangelist |
810 | */ |
811 | |
812 | qoutputrangelist QSensor::outputRanges() const |
813 | { |
814 | Q_D(const QSensor); |
815 | return d->outputRanges; |
816 | } |
817 | |
818 | /*! |
819 | \property QSensor::outputRange |
820 | \brief the output range in use by the sensor. |
821 | |
822 | This value represents the index in the QSensor::outputRanges list to use. |
823 | |
824 | Setting this property is not portable and can cause conflicts with other |
825 | applications. Check with the sensor backend and platform documentation for |
826 | any policy regarding multiple applications requesting an output range. |
827 | |
828 | The default value (-1) means that the app does not care what the output range is. |
829 | |
830 | Note that there is no mechanism to determine the current output range in use by the |
831 | platform. |
832 | |
833 | \sa QSensor::outputRanges |
834 | */ |
835 | |
836 | int QSensor::outputRange() const |
837 | { |
838 | Q_D(const QSensor); |
839 | return d->outputRange; |
840 | } |
841 | |
842 | void QSensor::setOutputRange(int index) |
843 | { |
844 | Q_D(QSensor); |
845 | if (index == -1 || !isConnectedToBackend()) { |
846 | d->outputRange = index; |
847 | return; |
848 | } |
849 | bool warn = true; |
850 | if (index >= 0 && index < d->outputRanges.count()) { |
851 | warn = false; |
852 | d->outputRange = index; |
853 | } |
854 | if (warn) { |
855 | qWarning() << "setOutputRange:" << index << "is not supported by the sensor." ; |
856 | } |
857 | } |
858 | |
859 | /*! |
860 | \property QSensor::description |
861 | \brief a descriptive string for the sensor. |
862 | */ |
863 | |
864 | QString QSensor::description() const |
865 | { |
866 | Q_D(const QSensor); |
867 | return d->description; |
868 | } |
869 | |
870 | /*! |
871 | \property QSensor::error |
872 | \brief the last error code set on the sensor. |
873 | |
874 | Note that error codes are sensor-specific. |
875 | */ |
876 | |
877 | int QSensor::error() const |
878 | { |
879 | Q_D(const QSensor); |
880 | return d->error; |
881 | } |
882 | |
883 | /*! |
884 | \enum QSensor::AxesOrientationMode |
885 | \since 5.1 |
886 | |
887 | Describes how reading values are affected by the screen orientation. |
888 | |
889 | \value FixedOrientation No automatic rotation is applied to the reading values. |
890 | |
891 | \value AutomaticOrientation The reading values are automatically rotated based on the screen |
892 | orientation. |
893 | |
894 | \value UserOrientation The reading values are rotated based on the angle of the userOrientation property. |
895 | |
896 | \sa QSensor::axesOrientationMode |
897 | */ |
898 | |
899 | /*! |
900 | \property QSensor::axesOrientationMode |
901 | \since 5.1 |
902 | \brief The mode that affects how the screen orientation changes reading values. |
903 | |
904 | When set to FixedOrientation, which is the default mode, no automatic rotation is applied to |
905 | the reading. This is the only mode available for backends that do not support the |
906 | QSensor::AxesOrientation feature. |
907 | |
908 | When set to AutomaticOrientation, the reading values are automatically rotated when the |
909 | screen orientation changes. In effect, the screen orientation is canceled out. |
910 | |
911 | As an example, assume the device is rotated by 180 degrees and therefore the screen orientation |
912 | also is rotated by 180 degrees from the native orientation. Without automatic axes orientation, |
913 | the reading values would now be changed: Both the X and the Y values would be negated, forcing |
914 | an application developer to manually cancel out the negation in application code. Automatic |
915 | axes orientation does this automatically, in this mode the X and Y values would be the same as |
916 | with the default screen orientation. |
917 | |
918 | This automatic rotation of the axes is handy is some usecases, for example in a bubble level |
919 | application that measures how level a surface is by looking at the X axis value of an |
920 | accelerometer. When the device and screen orientation change by 90 degrees, an application |
921 | developer does not need to change anything, he can continue using the X axis value even though |
922 | the device is rotated. Without automatic axes orientation, the application developer would need |
923 | to look at the Y values instead, thereby adding code to the application that reads from a |
924 | different axis depending on the screen orientation. |
925 | |
926 | The UserOrientation mode is quite similar to AutomaticOrientation, only that the screen orientation |
927 | is manually controlled instead of automatically determined. The angle of the userOrientation |
928 | property is then used for rotating the reading values. |
929 | |
930 | Since the rotation of the reading values is based on the screen orientation, Z values will never |
931 | change, as the Z axis is perpendicular to the screen. |
932 | As screen orientation changes in 90 degree steps, rotating the reading values is also done in |
933 | steps of 90 degrees. |
934 | |
935 | This property is only used for orientable sensors. |
936 | */ |
937 | |
938 | QSensor::AxesOrientationMode QSensor::axesOrientationMode() const |
939 | { |
940 | Q_D(const QSensor); |
941 | return d->axesOrientationMode; |
942 | } |
943 | |
944 | void QSensor::setAxesOrientationMode(QSensor::AxesOrientationMode axesOrientationMode) |
945 | { |
946 | Q_D(QSensor); |
947 | if (d->axesOrientationMode != axesOrientationMode) { |
948 | d->axesOrientationMode = axesOrientationMode; |
949 | emit axesOrientationModeChanged(axesOrientationMode); |
950 | } |
951 | } |
952 | |
953 | /*! |
954 | \property QSensor::currentOrientation |
955 | \since 5.1 |
956 | \brief The current orientation that is used for rotating the reading values. |
957 | |
958 | This might not be the same as the screen orientation. For example, in the FixedOrientation mode, |
959 | the reading values are not rotated, and therefore the property is 0. |
960 | |
961 | In the UserOrientation mode, the readings are rotated based on the userOrientation property, |
962 | and therefore this property is equal to the userOrientation property. |
963 | |
964 | In the AutomaticOrientation mode, the readings are rotated based on the screen orientation, |
965 | and therefore this property will be equal to the current screen orientation. |
966 | |
967 | This property is set by the backend and only valid for orientable sensors. |
968 | */ |
969 | |
970 | int QSensor::currentOrientation() const |
971 | { |
972 | Q_D(const QSensor); |
973 | return d->currentOrientation; |
974 | } |
975 | |
976 | /*! |
977 | \since 5.1 |
978 | Sets the current screen orientation to \a currentOrientation. This is to be called from the |
979 | backend whenever the screen orientation or the userOrientation property changes. |
980 | */ |
981 | void QSensor::setCurrentOrientation(int currentOrientation) |
982 | { |
983 | Q_D(QSensor); |
984 | if (d->currentOrientation != currentOrientation) { |
985 | d->currentOrientation = currentOrientation; |
986 | emit currentOrientationChanged(currentOrientation); |
987 | } |
988 | } |
989 | |
990 | /*! |
991 | \property QSensor::userOrientation |
992 | \since 5.1 |
993 | \brief The angle used for rotating the reading values in the UserOrientation mode. |
994 | |
995 | When the axesOrientationMode property is set to UserOrientation, the angle for rotating the |
996 | reading values is taken from this property. In other modes, the property has no effect. |
997 | |
998 | The default is 0. The only valid values are 0, 90, 180 and 270, as those are the only possible |
999 | screen orientations. |
1000 | |
1001 | This property is only valid for orientable sensors. |
1002 | */ |
1003 | |
1004 | int QSensor::userOrientation() const |
1005 | { |
1006 | Q_D(const QSensor); |
1007 | return d->userOrientation; |
1008 | } |
1009 | |
1010 | void QSensor::setUserOrientation(int userOrientation) |
1011 | { |
1012 | Q_D(QSensor); |
1013 | if (d->userOrientation != userOrientation) { |
1014 | d->userOrientation = userOrientation; |
1015 | emit userOrientationChanged(userOrientation); |
1016 | } |
1017 | } |
1018 | |
1019 | /*! |
1020 | \fn QSensor::sensorError(int error) |
1021 | |
1022 | This signal is emitted when an \a error code is set on the sensor. |
1023 | Note that some errors will cause the sensor to stop working. |
1024 | You should call isActive() to determine if the sensor is still running. |
1025 | */ |
1026 | |
1027 | /*! |
1028 | \fn QSensor::availableSensorsChanged() |
1029 | |
1030 | This signal is emitted when the list of available sensors has changed. |
1031 | The sensors available to a program will not generally change over time |
1032 | however some of the available sensors may represent hardware that is not |
1033 | permanently connected. For example, a game controller that is connected |
1034 | via bluetooth would become available when it was on and would become |
1035 | unavailable when it was off. |
1036 | |
1037 | \sa QSensor::sensorTypes(), QSensor::sensorsForType() |
1038 | */ |
1039 | |
1040 | /*! |
1041 | \property QSensor::maxBufferSize |
1042 | |
1043 | The property holds the maximum buffer size. |
1044 | |
1045 | Note that this may be 1, in which case the sensor does not support any form of buffering. |
1046 | In that case, isFeatureSupported(QSensor::Buffering) will also return false. |
1047 | |
1048 | \sa QSensor::bufferSize, QSensor::efficientBufferSize |
1049 | */ |
1050 | |
1051 | int QSensor::maxBufferSize() const |
1052 | { |
1053 | Q_D(const QSensor); |
1054 | return d->maxBufferSize; |
1055 | } |
1056 | |
1057 | /*! |
1058 | \since 5.1 |
1059 | Sets the maximum buffer size to \a maxBufferSize. This is to be called from the |
1060 | backend. |
1061 | */ |
1062 | void QSensor::setMaxBufferSize(int maxBufferSize) |
1063 | { |
1064 | Q_D(QSensor); |
1065 | if (d->maxBufferSize != maxBufferSize) { |
1066 | d->maxBufferSize = maxBufferSize; |
1067 | emit maxBufferSizeChanged(maxBufferSize); |
1068 | } |
1069 | } |
1070 | |
1071 | /*! |
1072 | \property QSensor::efficientBufferSize |
1073 | |
1074 | The property holds the most efficient buffer size. Normally this is 1 (which means |
1075 | no particular size is most efficient). Some sensor drivers have a FIFO buffer which |
1076 | makes it more efficient to deliver the FIFO's size worth of readings at one time. |
1077 | |
1078 | \sa QSensor::bufferSize, QSensor::maxBufferSize |
1079 | */ |
1080 | |
1081 | int QSensor::efficientBufferSize() const |
1082 | { |
1083 | Q_D(const QSensor); |
1084 | return d->efficientBufferSize; |
1085 | } |
1086 | |
1087 | /*! |
1088 | \since 5.1 |
1089 | Sets the efficient buffer size to \a efficientBufferSize. This is to be called from the |
1090 | backend. |
1091 | */ |
1092 | void QSensor::setEfficientBufferSize(int efficientBufferSize) |
1093 | { |
1094 | Q_D(QSensor); |
1095 | if (d->efficientBufferSize != efficientBufferSize) { |
1096 | d->efficientBufferSize = efficientBufferSize; |
1097 | emit efficientBufferSizeChanged(efficientBufferSize); |
1098 | } |
1099 | } |
1100 | |
1101 | /*! |
1102 | \property QSensor::bufferSize |
1103 | |
1104 | This property holds the size of the buffer. By default, the buffer size is 1, |
1105 | which means no buffering. |
1106 | If the maximum buffer size is 1, then buffering is not supported |
1107 | by the sensor. |
1108 | |
1109 | Setting bufferSize greater than maxBufferSize will cause maxBufferSize to be used. |
1110 | |
1111 | Buffering is turned on when bufferSize is greater than 1. The sensor will collect |
1112 | the requested number of samples and deliver them all to the application at one time. |
1113 | They will be delivered to the application as a burst of changed readings so it is |
1114 | particularly important that the application processes each reading immediately or |
1115 | saves the values somewhere else. |
1116 | |
1117 | If stop() is called when buffering is on-going, the partial buffer is not delivered. |
1118 | |
1119 | When the sensor is started with buffering option, values are collected from that |
1120 | moment onwards. There is no pre-existing buffer that can be utilized. |
1121 | |
1122 | Some backends only support enabling or disabling the buffer and do not give |
1123 | control over the size. In this case, the maxBufferSize and efficientBufferSize properties |
1124 | might not be set at all, even though buffering is supported. Setting the bufferSize property |
1125 | to any value greater than 1 will enable buffering. After the sensor has been started, |
1126 | the bufferSize property will be set to the actual value by the backend. |
1127 | |
1128 | \sa QSensor::maxBufferSize, QSensor::efficientBufferSize |
1129 | */ |
1130 | |
1131 | int QSensor::bufferSize() const |
1132 | { |
1133 | Q_D(const QSensor); |
1134 | return d->bufferSize; |
1135 | } |
1136 | |
1137 | void QSensor::setBufferSize(int bufferSize) |
1138 | { |
1139 | Q_D(QSensor); |
1140 | if (d->bufferSize != bufferSize) { |
1141 | d->bufferSize = bufferSize; |
1142 | emit bufferSizeChanged(bufferSize); |
1143 | } |
1144 | } |
1145 | |
1146 | // ===================================================================== |
1147 | |
1148 | /*! |
1149 | \class QSensorFilter |
1150 | \ingroup sensors_main |
1151 | \inmodule QtSensors |
1152 | |
1153 | \brief The QSensorFilter class provides an efficient |
1154 | callback facility for asynchronous notifications of |
1155 | sensor changes. |
1156 | |
1157 | Some sensors (eg. the accelerometer) are often accessed very frequently. |
1158 | This may be slowed down by the use of signals and slots. |
1159 | The QSensorFilter interface provides a more efficient way for the |
1160 | sensor to notify your class that the sensor has changed. |
1161 | |
1162 | Additionally, multiple filters can be added to a sensor. They are called |
1163 | in order and each filter has the option to modify the values in the reading |
1164 | or to suppress the reading altogether. |
1165 | |
1166 | Note that the values in the class returned by QSensor::reading() will |
1167 | not be updated until after the filters have been run. |
1168 | |
1169 | \sa filter() |
1170 | */ |
1171 | |
1172 | /*! |
1173 | \internal |
1174 | */ |
1175 | QSensorFilter::QSensorFilter() |
1176 | : m_sensor(0) |
1177 | { |
1178 | } |
1179 | |
1180 | /*! |
1181 | Notifies the attached sensor (if any) that the filter is being destroyed. |
1182 | */ |
1183 | QSensorFilter::~QSensorFilter() |
1184 | { |
1185 | if (m_sensor) |
1186 | m_sensor->removeFilter(filter: this); |
1187 | } |
1188 | |
1189 | /*! |
1190 | \fn QSensorFilter::filter(QSensorReading *reading) |
1191 | |
1192 | This function is called when the sensor \a reading changes. |
1193 | |
1194 | The filter can modify the reading. |
1195 | |
1196 | Returns true to allow the next filter to receive the value. |
1197 | If this is the last filter, returning true causes the signal |
1198 | to be emitted and the value is stored in the sensor. |
1199 | |
1200 | Returns false to drop the reading. |
1201 | */ |
1202 | |
1203 | /*! |
1204 | \internal |
1205 | */ |
1206 | void QSensorFilter::setSensor(QSensor *sensor) |
1207 | { |
1208 | m_sensor = sensor; |
1209 | } |
1210 | |
1211 | // ===================================================================== |
1212 | |
1213 | /*! |
1214 | \class QSensorReading |
1215 | \ingroup sensors_main |
1216 | \inmodule QtSensors |
1217 | |
1218 | \brief The QSensorReading class holds the readings from the sensor. |
1219 | |
1220 | Note that QSensorReading is not particularly useful by itself. The interesting |
1221 | data for each sensor is defined in a sub-class of QSensorReading. |
1222 | */ |
1223 | |
1224 | /*! |
1225 | \internal |
1226 | */ |
1227 | QSensorReading::QSensorReading(QObject *parent, QSensorReadingPrivate *_d) |
1228 | : QObject(parent) |
1229 | , d(_d?_d:new QSensorReadingPrivate) |
1230 | { |
1231 | } |
1232 | |
1233 | /*! |
1234 | \internal |
1235 | */ |
1236 | QSensorReading::~QSensorReading() |
1237 | { |
1238 | } |
1239 | |
1240 | /*! |
1241 | \property QSensorReading::timestamp |
1242 | \brief the timestamp of the reading. |
1243 | |
1244 | Timestamps values are microseconds since a fixed point. |
1245 | You can use timestamps to see how far apart two sensor readings are. |
1246 | |
1247 | Note that sensor timestamps from different sensors may not be directly |
1248 | comparable (as they may choose different fixed points for their reference). |
1249 | |
1250 | \b{Note that some platforms do not deliver timestamps correctly}. |
1251 | Applications should be prepared for occasional issues that cause timestamps to jump |
1252 | backwards. |
1253 | */ |
1254 | |
1255 | /*! |
1256 | Returns the timestamp of the reading. |
1257 | */ |
1258 | quint64 QSensorReading::timestamp() const |
1259 | { |
1260 | return d->timestamp; |
1261 | } |
1262 | |
1263 | /*! |
1264 | Sets the \a timestamp of the reading. |
1265 | */ |
1266 | void QSensorReading::setTimestamp(quint64 timestamp) |
1267 | { |
1268 | d->timestamp = timestamp; |
1269 | } |
1270 | |
1271 | /*! |
1272 | Returns the number of extra properties that the reading has. |
1273 | |
1274 | Note that this does not count properties declared in QSensorReading. |
1275 | |
1276 | As an example, this returns 3 for QAccelerometerReading because |
1277 | there are 3 properties defined in that class. |
1278 | */ |
1279 | int QSensorReading::valueCount() const |
1280 | { |
1281 | const QMetaObject *mo = metaObject(); |
1282 | return mo->propertyCount() - mo->propertyOffset(); |
1283 | } |
1284 | |
1285 | /*! |
1286 | Returns the value of the property at \a index. |
1287 | |
1288 | Note that this function is slower than calling the data function directly. |
1289 | |
1290 | Here is an example of getting a property via the different mechanisms available. |
1291 | |
1292 | Accessing directly provides the best performance but requires compile-time knowledge |
1293 | of the data you are accessing. |
1294 | |
1295 | \code |
1296 | QAccelerometerReading *reading = ...; |
1297 | qreal x = reading->x(); |
1298 | \endcode |
1299 | |
1300 | You can also access a property by name. To do this you must call QObject::property(). |
1301 | |
1302 | \code |
1303 | qreal x = reading->property("x").value<qreal>(); |
1304 | \endcode |
1305 | |
1306 | Finally, you can access values via numeric index. |
1307 | |
1308 | \code |
1309 | qreal x = reading->value(0).value<qreal>(); |
1310 | \endcode |
1311 | |
1312 | Note that value() can only access properties declared with Q_PROPERTY() in sub-classes |
1313 | of QSensorReading. |
1314 | |
1315 | \sa valueCount(), QObject::property() |
1316 | */ |
1317 | QVariant QSensorReading::value(int index) const |
1318 | { |
1319 | // get them meta-object |
1320 | const QMetaObject *mo = metaObject(); |
1321 | |
1322 | // determine the index of the property we want |
1323 | index += mo->propertyOffset(); |
1324 | |
1325 | // get the meta-property |
1326 | QMetaProperty property = mo->property(index); |
1327 | |
1328 | // read the property |
1329 | return property.read(obj: this); |
1330 | } |
1331 | |
1332 | /*! |
1333 | \fn QSensorReading::copyValuesFrom(QSensorReading *other) |
1334 | \internal |
1335 | |
1336 | Copy values from other into this reading. Implemented by sub-classes |
1337 | using the DECLARE_READING() and IMPLEMENT_READING() macros. |
1338 | |
1339 | Note that this method should only be called by QSensorBackend. |
1340 | */ |
1341 | void QSensorReading::copyValuesFrom(QSensorReading *other) |
1342 | { |
1343 | QSensorReadingPrivate *my_ptr = d.data(); |
1344 | QSensorReadingPrivate *other_ptr = other->d.data(); |
1345 | /* Do a direct copy of the private class */ |
1346 | *(my_ptr) = *(other_ptr); |
1347 | } |
1348 | |
1349 | /*! |
1350 | \fn QSensorReading::d_ptr() |
1351 | \internal |
1352 | No longer used. Exists to keep the winscw build happy. |
1353 | */ |
1354 | |
1355 | /*! |
1356 | \macro DECLARE_READING(classname) |
1357 | \relates QSensorReading |
1358 | \brief The DECLARE_READING macro adds some required methods to a reading class. |
1359 | |
1360 | This macro should be used for all reading classes. Pass the \a classname of your reading class. |
1361 | |
1362 | \code |
1363 | class MyReading : public QSensorReading |
1364 | { |
1365 | Q_OBJECT |
1366 | Q_PROPERTY(qreal myprop READ myprop) |
1367 | DECLARE_READING(MyReading) |
1368 | public: |
1369 | qreal myprop() const; |
1370 | vod setMyprop(qreal myprop); |
1371 | }; |
1372 | \endcode |
1373 | |
1374 | \sa IMPLEMENT_READING() |
1375 | */ |
1376 | |
1377 | /*! |
1378 | \macro IMPLEMENT_READING(classname) |
1379 | \relates QSensorReading |
1380 | \brief The IMPLEMENT_READING macro implements the required methods for a reading class. |
1381 | |
1382 | This macro should be used for all reading classes. It should be placed into a single compilation |
1383 | unit (source file), not into a header file. Pass the \a classname of your reading class. |
1384 | |
1385 | \code |
1386 | IMPLEMENT_READING(MyReading) |
1387 | \endcode |
1388 | |
1389 | \sa DECLARE_READING() |
1390 | */ |
1391 | |
1392 | QT_END_NAMESPACE |
1393 | |
1394 | #include "moc_qsensor.cpp" |
1395 | |
1396 | |