diff options
Diffstat (limited to 'examples/sensors/sensorsshowcase')
27 files changed, 1222 insertions, 0 deletions
diff --git a/examples/sensors/sensorsshowcase/Accelerometer.qml b/examples/sensors/sensorsshowcase/Accelerometer.qml new file mode 100644 index 00000000..a22e1404 --- /dev/null +++ b/examples/sensors/sensorsshowcase/Accelerometer.qml @@ -0,0 +1,70 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +pragma ComponentBehavior: Bound +import QtQuick +import QtQuick.Layouts +import QtSensors + +Item { + id: root + + required property int fontSize + required property int imageSize + + //! [0] + Accelerometer { + id: accelerometer + + property real x: 0 + property real y: 0 + property real z: 0 + + active: true + dataRate: 25 + + onReadingChanged: { + x = (reading as AccelerometerReading).x + y = (reading as AccelerometerReading).y + z = (reading as AccelerometerReading).z + imageTranslation.x = -x * 10 + imageTranslation.y = y * 10 + } + } + //! [0] + ColumnLayout { + id: layout + + anchors.fill: parent + spacing: 10 + + Image { + id: image + + Layout.alignment: Qt.AlignCenter + Layout.preferredHeight: root.imageSize + Layout.preferredWidth: root.imageSize + fillMode: Image.PreserveAspectFit + source: "images/qt_logo.png" + + transform: [ + Translate { + id: imageTranslation + + x: 0 + y: 0 + } + ] + } + + ProgressXYZBar { + Layout.fillWidth: true + fontSize: root.fontSize + xText: "X: " + accelerometer.x.toFixed(2) + xValue: 0.5 + (accelerometer.x / 100) + yText: "Y: " + accelerometer.y.toFixed(2) + yValue: 0.5 + (accelerometer.y / 100) + zText: "Z: " + accelerometer.z.toFixed(2) + zValue: 0.5 + (accelerometer.z / 100) + } + } +} diff --git a/examples/sensors/sensorsshowcase/CMakeLists.txt b/examples/sensors/sensorsshowcase/CMakeLists.txt new file mode 100644 index 00000000..b949213a --- /dev/null +++ b/examples/sensors/sensorsshowcase/CMakeLists.txt @@ -0,0 +1,72 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(sensorsshowcase LANGUAGES CXX) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/sensors/sensorsshowcase") +find_package(Qt6 REQUIRED COMPONENTS Core Gui Quick Svg Sensors) +qt_standard_project_setup(REQUIRES 6.5) + +qt_add_executable(sensorsshowcase + main.cpp +) + +set_target_properties(sensorsshowcase PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +if(ANDROID) + set_property(TARGET sensorsshowcase PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR + ${CMAKE_CURRENT_SOURCE_DIR}/android) +endif() + +if(APPLE AND IOS) + set_property(TARGET sensorsshowcase PROPERTY + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist" + ) +else() + # default search path for the config file is "qrc:/" + qt_add_resources(sensorsshowcase "resources" + FILES qtquickcontrols2.conf) +endif() + +qt_add_qml_module(sensorsshowcase + URI SensorShowcaseModule + VERSION 1.0 + QML_FILES + "Main.qml" + "Accelerometer.qml" + "Compass.qml" + "Gyroscope.qml" + "Magnetometer.qml" + "Proximity.qml" + "ProgressXYZBar.qml" + RESOURCES + "images/compass.svg" + "images/magnet.svg" + "images/qt_logo.png" + SOURCES + sensorsupport.h +) + +target_link_libraries(sensorsshowcase + PRIVATE + Qt::Core + Qt::Gui + Qt::Quick + Qt::Svg + Qt::Sensors +) + + +install(TARGETS sensorsshowcase + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/sensors/sensorsshowcase/Compass.qml b/examples/sensors/sensorsshowcase/Compass.qml new file mode 100644 index 00000000..b4bc5ff1 --- /dev/null +++ b/examples/sensors/sensorsshowcase/Compass.qml @@ -0,0 +1,61 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +pragma ComponentBehavior: Bound +import QtQuick +import QtQuick.Layouts +import QtSensors + +Item { + id: root + + required property int fontSize + required property int imageSize + property alias isActive: compass.active + + property real azimuth: 30 + + Compass { + id: compass + active: true + dataRate: 7 + onReadingChanged: root.azimuth = -(reading as CompassReading).azimuth + } + + ColumnLayout { + id: layout + + anchors.fill: parent + spacing: 10 + + Image { + id: arrow + + Layout.alignment: Qt.AlignHCenter + Layout.preferredWidth: root.imageSize * 1.25 + Layout.fillHeight: true + + source: "images/compass.svg" + fillMode: Image.PreserveAspectFit + rotation: root.azimuth + } + + Rectangle { + id: separator + + Layout.topMargin: 10 + Layout.preferredWidth: parent.width * 0.75 + Layout.preferredHeight: 1 + Layout.alignment: Qt.AlignHCenter + color: "black" + } + + Text { + id: info + Layout.fillWidth: true + Layout.fillHeight: true + Layout.topMargin: 10 + text: "Azimuth: " + root.azimuth.toFixed(2) + "°" + font.pixelSize: root.fontSize + } + } +} diff --git a/examples/sensors/sensorsshowcase/Gyroscope.qml b/examples/sensors/sensorsshowcase/Gyroscope.qml new file mode 100644 index 00000000..9f0ffd2f --- /dev/null +++ b/examples/sensors/sensorsshowcase/Gyroscope.qml @@ -0,0 +1,128 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +pragma ComponentBehavior: Bound +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtSensors + +Item { + id: root + + required property int fontSize + required property int imageSize + + function resetRotations() : void + { + imageXRotation.angle = 0 + imageYRotation.angle = 0 + imageZRotation.angle = 0 + } + + //! [0] + Gyroscope { + id: gyroscope + + property var lastTimeStamp: 0 + property real x: 0 + property real y: 0 + property real z: 0 + + active: true + dataRate: 25 + + onReadingChanged: { + x = (reading as GyroscopeReading).x + y = (reading as GyroscopeReading).y + z = (reading as GyroscopeReading).z + let firstCall = false + if (lastTimeStamp == 0) { + firstCall = true + } + let timeSinceLast = reading.timestamp - lastTimeStamp + lastTimeStamp = reading.timestamp + + //Skipping the initial time jump from 0 + if (firstCall === true) + return + let normalizedX = x * (timeSinceLast / 1000000) + imageXRotation.angle += normalizedX + let normalizedY = y * (timeSinceLast / 1000000) + imageYRotation.angle -= normalizedY + let normalizedZ = z * (timeSinceLast / 1000000) + imageZRotation.angle += normalizedZ + } + } + //! [0] + ColumnLayout { + id: layout + + anchors.fill: parent + spacing: 10 + + Image { + id: image + + Layout.alignment: Qt.AlignHCenter + Layout.fillHeight: true + Layout.preferredWidth: root.imageSize + fillMode: Image.PreserveAspectFit + source: "images/qt_logo.png" + + transform: [ + Rotation { + id: imageXRotation + + angle: 0 + axis.x: 1 + axis.y: 0 + axis.z: 0 + origin.x: layout.width / 2 + origin.y: layout.height / 3 + }, + Rotation { + id: imageYRotation + + angle: 0 + axis.x: 0 + axis.y: 1 + axis.z: 0 + origin.x: layout.width / 2 + origin.y: layout.height / 3 + }, + Rotation { + id: imageZRotation + + angle: 0 + axis.x: 0 + axis.y: 0 + axis.z: 1 + origin.x: layout.width / 2 + origin.y: layout.height / 3 + } + ] + } + + ProgressXYZBar { + Layout.fillWidth: true + Layout.topMargin: 20 + fontSize: root.fontSize + xText: "X: " + gyroscope.x.toFixed(2) + xValue: 0.5 + (gyroscope.x / 1000) + yText: "Y: " + gyroscope.y.toFixed(2) + yValue: 0.5 + (gyroscope.y / 1000) + zText: "Z: " + gyroscope.z.toFixed(2) + zValue: 0.5 + (gyroscope.z / 1000) + } + + Button { + Layout.alignment: Qt.AlignHCenter + Layout.topMargin: 20 + Layout.bottomMargin: 10 + Layout.preferredWidth: parent.width / 2 + Layout.preferredHeight: 60 + onClicked: root.resetRotations() + text: "Reset rotation" + } + } +} diff --git a/examples/sensors/sensorsshowcase/Info.plist b/examples/sensors/sensorsshowcase/Info.plist new file mode 100644 index 00000000..61d01e5a --- /dev/null +++ b/examples/sensors/sensorsshowcase/Info.plist @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDisplayName</key> + <string>sensorsshowcase</string> + <key>CFBundleExecutable</key> + <string>sensorsshowcase</string> + <key>CFBundleGetInfoString</key> + <string>Created by Qt/QMake</string> + <key>CFBundleIdentifier</key> + <string>com.qt.sensorsshowcase</string> + <key>CFBundleName</key> + <string>sensorsshowcase</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1.0</string> + <key>LSRequiresIPhoneOS</key> + <true/> + <key>UILaunchStoryboardName</key> + <string>LaunchScreen</string> + <key>UISupportedInterfaceOrientations</key> + <array> + <string>UIInterfaceOrientationPortrait</string> + </array> +</dict> +</plist> diff --git a/examples/sensors/sensorsshowcase/Magnetometer.qml b/examples/sensors/sensorsshowcase/Magnetometer.qml new file mode 100644 index 00000000..551f8627 --- /dev/null +++ b/examples/sensors/sensorsshowcase/Magnetometer.qml @@ -0,0 +1,68 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +pragma ComponentBehavior: Bound +import QtQuick +import QtQuick.Layouts +import QtSensors + +Item { + id: root + + required property int fontSize + required property int imageSize + + property real magnetRotation: 40 + property real magnetometerX: 0 + property real magnetometerY: 0 + property real magnetometerZ: 0 + property int barScaleFactor: 10000 + + //! [0] + Magnetometer { + id: magnetometer + active: true + dataRate: 25 + onReadingChanged: { + root.magnetometerX = (reading as MagnetometerReading).x + root.magnetometerY = (reading as MagnetometerReading).y + root.magnetometerZ = (reading as MagnetometerReading).z + root.magnetRotation = + ((Math.atan2(root.magnetometerX, root.magnetometerY) / Math.PI) * 180) + } + } + //! [0] + + ColumnLayout { + id: layout + + anchors.fill: parent + spacing: 10 + + Image { + id: image + + Layout.alignment: Qt.AlignHCenter + Layout.bottomMargin: 20 + Layout.preferredWidth: root.imageSize * 0.9 + Layout.preferredHeight: root.imageSize * 0.9 + + source: "images/magnet.svg" + fillMode: Image.PreserveAspectFit + rotation: root.magnetRotation + } + + ProgressXYZBar { + Layout.fillWidth: true + fontSize: root.fontSize + + xText: "X: " + root.magnetometerX.toFixed(9) + xValue: 0.5 + (root.magnetometerX * root.barScaleFactor) + + yText: "Y: " + root.magnetometerY.toFixed(9) + yValue: 0.5 + (root.magnetometerY * root.barScaleFactor) + + zText: "Z: " + root.magnetometerZ.toFixed(9) + zValue: 0.5 + (root.magnetometerZ * root.barScaleFactor) + } + } +} diff --git a/examples/sensors/sensorsshowcase/Main.qml b/examples/sensors/sensorsshowcase/Main.qml new file mode 100644 index 00000000..4587ba21 --- /dev/null +++ b/examples/sensors/sensorsshowcase/Main.qml @@ -0,0 +1,116 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ApplicationWindow { + id: root + + readonly property int defaultFontSize: 22 + readonly property int imageSize: width / 2 + + width: 420 + height: 760 + visible: true + title: "Sensors Showcase" + + header : ToolBar { + RowLayout { + anchors.fill: parent + anchors.leftMargin: 10 + anchors.rightMargin: 10 + ToolButton { + id: back + text: qsTr("Back") + font.pixelSize: root.defaultFontSize - 4 + visible: stack.depth > 1 + onClicked: { + stack.pop(); + heading.text = root.title; + } + Layout.alignment: Qt.AlignLeft + } + Label { + id: heading + text: root.title + font.pixelSize: root.defaultFontSize + font.weight: Font.Medium + verticalAlignment: Qt.AlignVCenter + Layout.alignment: Qt.AlignCenter + Layout.preferredHeight: 55 + } + Item { + visible: back.visible + Layout.preferredWidth: back.width + } + } + } + + StackView { + id: stack + + // Pushes the object and forwards the properties + function pusher(object : string) : void { + // Trim the suffix and set it as new heading + heading.text = object.split(".")[0] + return stack.push(object, { + fontSize: root.defaultFontSize, + imageSize: root.imageSize + }) + } + + anchors.fill: parent + anchors.margins: width / 12 + + initialItem: Item { + ColumnLayout { + id: initialItem + + anchors.fill: parent + anchors.topMargin: 20 + anchors.bottomMargin: 20 + spacing: 5 + + component CustomButton: Button { + highlighted: true + font.pixelSize: root.defaultFontSize + font.letterSpacing: 1.5 + + Layout.alignment: Qt.AlignCenter + Layout.fillHeight: true + Layout.fillWidth: true + } + + CustomButton { + text: "Accelerometer" + onClicked: stack.pusher("Accelerometer.qml") + enabled: SensorSupport.hasAccelerometer() + } + CustomButton { + text: "Proximity" + onClicked: stack.pusher("Proximity.qml") + enabled: SensorSupport.hasProximity() + } + CustomButton { + text: "Compass" + onClicked: stack.pusher("Compass.qml") + enabled: SensorSupport.hasCompass() + } + CustomButton { + text: "Magnetometer" + onClicked: stack.pusher("Magnetometer.qml") + enabled: SensorSupport.hasMagnetometer() + } + CustomButton { + text: "Gyroscope" + onClicked: stack.pusher("Gyroscope.qml") + enabled: SensorSupport.hasGyroscope() + } + } + } + } + +} diff --git a/examples/sensors/sensorsshowcase/ProgressXYZBar.qml b/examples/sensors/sensorsshowcase/ProgressXYZBar.qml new file mode 100644 index 00000000..be7bf7ae --- /dev/null +++ b/examples/sensors/sensorsshowcase/ProgressXYZBar.qml @@ -0,0 +1,45 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +pragma ComponentBehavior: Bound +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +ColumnLayout { + id: root + spacing: 0 + + required property int fontSize + property alias xText: xBar.text + property alias xValue: xBar.value + property alias yText: yBar.text + property alias yValue: yBar.value + property alias zText: zBar.text + property alias zValue: zBar.value + + component NamedProgressBar: ColumnLayout { + property alias text: axes.text + property alias value: bar.value + Text { + id: axes + font.pixelSize: root.fontSize + Layout.fillWidth: true + } + ProgressBar { + id: bar + Layout.fillWidth: true + } + } + + NamedProgressBar { + id: xBar + } + + NamedProgressBar { + id: yBar + } + + NamedProgressBar { + id: zBar + } +} diff --git a/examples/sensors/sensorsshowcase/Proximity.qml b/examples/sensors/sensorsshowcase/Proximity.qml new file mode 100644 index 00000000..41121983 --- /dev/null +++ b/examples/sensors/sensorsshowcase/Proximity.qml @@ -0,0 +1,55 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +pragma ComponentBehavior: Bound +import QtQuick +import QtQuick.Layouts +import QtSensors + +Item { + id: root + + required property int imageSize + required property int fontSize + + property bool near: false + + ProximitySensor { + id: proximity + onReadingChanged: root.near = (reading as ProximityReading).near + active: true + } + + ColumnLayout { + id: layout + + anchors.fill: parent + spacing: 10 + + Image { + id: image + + Layout.alignment: Qt.AlignHCenter + Layout.preferredWidth: root.near ? root.imageSize : root.imageSize * 0.75 + Layout.fillHeight: true + + source: "images/qt_logo.png" + fillMode: Image.PreserveAspectFit + } + + Rectangle { + id: separator + Layout.topMargin: 10 + Layout.bottomMargin: 10 + Layout.preferredWidth: parent.width * 0.75 + Layout.preferredHeight: 1 + Layout.alignment: Qt.AlignHCenter + color: "black" + } + + Text { + Layout.fillHeight: true + font.pixelSize: root.fontSize + text: "Near: " + root.near + } + } +} diff --git a/examples/sensors/sensorsshowcase/android/AndroidManifest.xml b/examples/sensors/sensorsshowcase/android/AndroidManifest.xml new file mode 100644 index 00000000..359c0114 --- /dev/null +++ b/examples/sensors/sensorsshowcase/android/AndroidManifest.xml @@ -0,0 +1,57 @@ +<?xml version="1.0"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="org.qtproject.example.sensorsshowcase" + android:installLocation="auto" + android:versionCode="1" + android:versionName="1.0"> + <!-- The comment below will be replaced with dependencies permissions upon deployment. + Remove the comment if you do not require these default permissions. --> + <!-- %%INSERT_PERMISSIONS --> + + <!-- The comment below will be replaced with dependencies permissions upon deployment. + Remove the comment if you do not require these default features. --> + <!-- %%INSERT_FEATURES --> + <supports-screens + android:anyDensity="true" + android:largeScreens="true" + android:normalScreens="true" + android:smallScreens="true" /> + <application + android:name="org.qtproject.qt.android.bindings.QtApplication" + android:extractNativeLibs="true" + android:hardwareAccelerated="true" + android:label="-- %%INSERT_APP_NAME%% --" + android:requestLegacyExternalStorage="true" + android:allowNativeHeapPointerTagging="false" + android:allowBackup="true" + android:fullBackupOnly="false" + android:icon="@drawable/icon"> + <activity + android:name="org.qtproject.qt.android.bindings.QtActivity" + android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density" + android:label="-- %%INSERT_APP_NAME%% --" + android:launchMode="singleTop" + android:screenOrientation="portrait" + android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + + <meta-data + android:name="android.app.lib_name" + android:value="-- %%INSERT_APP_LIB_NAME%% --" /> + + <meta-data android:name="android.app.arguments" + android:value="" /> + + <meta-data + android:name="android.app.extract_android_style" + android:value="minimal" /> + + <meta-data + android:name="android.app.background_running" + android:value="false" /> + </activity> + </application> +</manifest> diff --git a/examples/sensors/sensorsshowcase/android/res/drawable-hdpi/icon.png b/examples/sensors/sensorsshowcase/android/res/drawable-hdpi/icon.png Binary files differnew file mode 100644 index 00000000..5f61088b --- /dev/null +++ b/examples/sensors/sensorsshowcase/android/res/drawable-hdpi/icon.png diff --git a/examples/sensors/sensorsshowcase/android/res/drawable-ldpi/icon.png b/examples/sensors/sensorsshowcase/android/res/drawable-ldpi/icon.png Binary files differnew file mode 100644 index 00000000..605497de --- /dev/null +++ b/examples/sensors/sensorsshowcase/android/res/drawable-ldpi/icon.png diff --git a/examples/sensors/sensorsshowcase/android/res/drawable-mdpi/icon.png b/examples/sensors/sensorsshowcase/android/res/drawable-mdpi/icon.png Binary files differnew file mode 100644 index 00000000..3eb10832 --- /dev/null +++ b/examples/sensors/sensorsshowcase/android/res/drawable-mdpi/icon.png diff --git a/examples/sensors/sensorsshowcase/android/res/drawable-xhdpi/icon.png b/examples/sensors/sensorsshowcase/android/res/drawable-xhdpi/icon.png Binary files differnew file mode 100644 index 00000000..a9e39f88 --- /dev/null +++ b/examples/sensors/sensorsshowcase/android/res/drawable-xhdpi/icon.png diff --git a/examples/sensors/sensorsshowcase/android/res/drawable-xxhdpi/icon.png b/examples/sensors/sensorsshowcase/android/res/drawable-xxhdpi/icon.png Binary files differnew file mode 100644 index 00000000..b489d81e --- /dev/null +++ b/examples/sensors/sensorsshowcase/android/res/drawable-xxhdpi/icon.png diff --git a/examples/sensors/sensorsshowcase/android/res/drawable-xxxhdpi/icon.png b/examples/sensors/sensorsshowcase/android/res/drawable-xxxhdpi/icon.png Binary files differnew file mode 100644 index 00000000..9443da63 --- /dev/null +++ b/examples/sensors/sensorsshowcase/android/res/drawable-xxxhdpi/icon.png diff --git a/examples/sensors/sensorsshowcase/doc/images/sensorsshowcase-gyroscope.webp b/examples/sensors/sensorsshowcase/doc/images/sensorsshowcase-gyroscope.webp Binary files differnew file mode 100644 index 00000000..0ff45403 --- /dev/null +++ b/examples/sensors/sensorsshowcase/doc/images/sensorsshowcase-gyroscope.webp diff --git a/examples/sensors/sensorsshowcase/doc/images/sensorsshowcase-mainview.webp b/examples/sensors/sensorsshowcase/doc/images/sensorsshowcase-mainview.webp Binary files differnew file mode 100644 index 00000000..b045b7ba --- /dev/null +++ b/examples/sensors/sensorsshowcase/doc/images/sensorsshowcase-mainview.webp diff --git a/examples/sensors/sensorsshowcase/doc/src/sensorsshowcase.qdoc b/examples/sensors/sensorsshowcase/doc/src/sensorsshowcase.qdoc new file mode 100644 index 00000000..d3d31c34 --- /dev/null +++ b/examples/sensors/sensorsshowcase/doc/src/sensorsshowcase.qdoc @@ -0,0 +1,78 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example sensorsshowcase + \title Sensors Showcase + \brief The Sensors Showcase example demonstrates sensor usage with visual examples. + \meta tag {sensors,quick,mobile} + \ingroup qtsensors-examples + \examplecategory {Mobile} + + \image sensorsshowcase-mainview.webp + + \section1 Overview + + On startup, the application shows a menu with buttons for the subviews for each sensor. + The sensor views instantiate the given sensor, display the sensor's values as numbers, + and also visualize them with a simple graphical representation. + + \section1 Main Menu + + The main view shows the title with the name of the application and a button + for each subview laid out evenly by a \c ColumnLayout. A \c StackView + manages the navigation between the subviews and the main menu. The + application checks the availability of the sensors during startup and + disables the buttons for the sensors that are not available. + + \note To simplify the example, the sensor availability is checked only once + during the startup. + + \section1 Accelerometer View + + The accelerometer view shows the current device acceleration values and moves around + an image with an amount that is opposite of the device acceleration giving the image + an inertia effect that is proportional with the movement of the device. + + Moving around the image happens in the accelerometer \c onReadingChanged method. + + \snippet sensorsshowcase/Accelerometer.qml 0 + + Whenever there is a new accelerometer value the image translation coordinates are + updated accordingly. + + \section1 Proximity View + + The proximity view shows an image that is enlarged whenever the proximity sensor of + the device is covered. + + \section1 Compass View + + The compass view shows a compass image that is rotated according to the Compass sensor + reading value making the compass turn towards north. + + \section1 Magnetometer View + + The magnetometer view displays a magnet image that is rotated around an amount that is + decided by the rotation angle of the vector given by the x and y magnetometer values. + This results in general in the same rotation as the compass gives, demonstrating one use + case of how the magnetometer readings can be used. Since the magnetometer provides + readings along all three axes, there is more freedom with how these readings can be used. + + \snippet sensorsshowcase/Magnetometer.qml 0 + + \section1 Gyroscope View + + \image sensorsshowcase-gyroscope.webp + + The gyroscope view also shows an image that is rotated around three axes with an amount + that is calculated from the gyroscope readings. Since the gyroscope provides relative + rotational change around the three spatial axes and the time between reading updates + can vary, the time of the readings are stored and the rotational change is normalized + based on the time passed between reading updates. + + \snippet sensorsshowcase/Gyroscope.qml 0 + + By pressing the reset button the image rotation is reset to 0. +*/ + diff --git a/examples/sensors/sensorsshowcase/images/compass.svg b/examples/sensors/sensorsshowcase/images/compass.svg new file mode 100644 index 00000000..009e6ffd --- /dev/null +++ b/examples/sensors/sensorsshowcase/images/compass.svg @@ -0,0 +1,222 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + width="123.29776mm" + height="123.29776mm" + viewBox="0 0 123.29776 123.29776" + version="1.1" + id="svg5" + inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)" + sodipodi:docname="compass.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <sodipodi:namedview + id="namedview7" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + inkscape:document-units="mm" + showgrid="false" + showborder="true" + inkscape:zoom="1.5554293" + inkscape:cx="118.61677" + inkscape:cy="123.76005" + inkscape:window-width="2560" + inkscape:window-height="1377" + inkscape:window-x="1912" + inkscape:window-y="72" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + lock-margins="true" + fit-margin-top="15" + fit-margin-left="15" + fit-margin-right="15" + fit-margin-bottom="15" /> + <defs + id="defs2" /> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="Layer 2" + style="display:inline" + transform="translate(7.215891,-13.196477)"> + <path + sodipodi:type="star" + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.88976;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path2691" + inkscape:flatsided="false" + sodipodi:sides="4" + sodipodi:cx="131.1535" + sodipodi:cy="547.11584" + sodipodi:r1="75.011292" + sodipodi:r2="15.353019" + sodipodi:arg1="0.77933767" + sodipodi:arg2="1.5647358" + inkscape:rounded="0" + inkscape:randomized="0" + d="m 184.51497,599.83441 -53.26842,-37.36583 -52.811613,38.00874 37.365833,-53.26843 -38.008738,-52.81161 53.268428,37.36583 52.81161,-38.00874 -37.36583,53.26843 z" + transform="matrix(0.45357635,0,0,0.48302392,-5.0551384,-189.42468)" /> + <circle + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path25062" + cx="54.432987" + cy="74.84536" + r="30" /> + <circle + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.579683;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="circle25206" + cx="54.432987" + cy="74.84536" + r="34.780952" /> + </g> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + style="display:inline" + transform="translate(7.215891,-13.196477)"> + <path + sodipodi:type="star" + style="fill:none;stroke:#000000;stroke-width:1.88976;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path846" + inkscape:flatsided="false" + sodipodi:sides="4" + sodipodi:cx="205.73099" + sodipodi:cy="282.8801" + sodipodi:r1="176.15717" + sodipodi:r2="35.231434" + sodipodi:arg1="1.5707963" + sodipodi:arg2="2.3561945" + inkscape:rounded="0" + inkscape:randomized="0" + d="M 205.73099,459.03726 180.8186,307.79248 29.573822,282.8801 180.8186,257.96771 l 24.91238,-151.24478 24.91239,151.24478 151.24478,24.91238 -151.24478,24.91239 z" + transform="scale(0.26458333)" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 54.432988,28.237108 2e-6,93.216502" + id="path991" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 7.8247403,74.845359 93.2164997,-3e-6" + id="path993" /> + <path + style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 47.841587,68.253956 C 61.024391,81.436759 61.024391,81.436759 61.024391,81.436759" + id="path995" /> + <path + style="fill:#ff0000;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="M 61.024391,68.253956 47.841587,81.436759" + id="path997" /> + <path + style="fill:#ff0000;stroke:#000000;stroke-width:0.607473;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 193.43534,269.62014 c -6.2322,-6.23407 -11.33698,-11.55089 -11.34397,-11.81517 -0.007,-0.26428 5.0921,-31.50414 11.33128,-69.4219 l 11.34397,-68.9414 0.0816,40.4123 c 0.0449,22.22675 0.0449,58.56721 0,80.75656 l -0.0816,40.34427 z" + id="path1073" + transform="scale(0.26458333)" /> + <path + style="fill:#aa0000;stroke:#000000;stroke-width:0.607473;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 206.57191,200.26456 c 0.0205,-44.46429 0.0937,-80.62717 0.16276,-80.36197 0.27012,1.03808 22.62323,137.13728 22.62323,137.74386 0,0.42036 -3.98335,4.62794 -11.41164,12.05401 l -11.41164,11.40825 z" + id="path1186" + transform="scale(0.26458333)" /> + <path + style="fill:#0000ff;stroke:#000000;stroke-width:0.607473;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 206.57191,365.49565 -0.0373,-80.84415 11.41164,11.40825 c 7.42829,7.42607 11.41164,11.63365 11.41164,12.05401 0,0.60657 -22.35311,136.70578 -22.62323,137.74386 -0.069,0.2652 -0.14225,-35.89769 -0.16276,-80.36197 z" + id="path1336" + transform="scale(0.26458333)" /> + <path + style="fill:#0000aa;fill-opacity:1;stroke:#000000;stroke-width:0.607473;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="M 193.41121,377.30741 C 187.17832,339.428 182.08439,308.218 182.09137,307.95187 c 0.007,-0.26613 5.14794,-5.61759 11.42434,-11.89212 l 11.41164,-11.40825 v 80.76379 c 0,44.42008 -0.0413,80.76378 -0.0918,80.76378 -0.0505,0 -5.19144,-30.99224 -11.42433,-68.87166 z" + id="path1412" + transform="scale(0.26458333)" /> + <path + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.607473;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 41.628379,282.04372 c 0.2652,-0.0654 31.724078,-5.25942 69.908621,-11.5423 l 69.42643,-11.4234 11.57959,11.57959 11.57958,11.57958 -81.4882,-0.0373 c -44.818513,-0.0205 -81.271221,-0.0908 -81.006021,-0.15619 z" + id="path2360" + transform="scale(0.26458333)" /> + <path + style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.607473;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 111.38404,295.24525 c -37.746813,-6.24278 -68.992206,-11.41247 -69.434206,-11.48821 -0.442001,-0.0757 35.865552,-0.15937 80.683446,-0.18586 l 81.48708,-0.0482 -11.56902,11.57237 c -6.36296,6.3648 -11.78675,11.55617 -12.05287,11.53638 -0.26612,-0.0198 -31.36762,-5.14373 -69.11443,-11.38651 z" + id="path2436" + transform="scale(0.26458333)" /> + <path + style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.607473;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 218.92415,270.65241 11.58478,-11.58478 69.42124,11.42566 c 38.18168,6.28411 69.63822,11.48048 69.90342,11.54749 0.2652,0.067 -36.18751,0.13862 -81.00602,0.15913 l -81.4882,0.0373 z" + id="path2475" + transform="scale(0.26458333)" /> + <path + style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.607473;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 218.91063,295.09538 -11.56902,-11.57237 81.48708,0.0373 c 44.81789,0.0205 81.2701,0.0921 81.0049,0.15913 -0.42568,0.10756 -139.03687,22.94832 -139.26393,22.94832 -0.0495,0 -5.29607,-5.20757 -11.65903,-11.57237 z" + id="path2514" + transform="scale(0.26458333)" /> + <path + style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.21495;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 51.111292,281.19388 c 0.5304,-0.13818 29.895283,-5.01467 65.255298,-10.83664 l 64.29093,-10.5854 10.92713,10.91122 10.92713,10.91123 -76.18242,-0.0746 c -41.900341,-0.041 -75.748469,-0.18764 -75.218068,-0.32583 z" + id="path2999" + transform="scale(0.26458333)" /> + <path + style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.21495;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m 219.88208,295.10818 -10.92236,-10.94226 76.17766,0.0508 c 41.89771,0.0279 75.88835,0.15784 75.53475,0.28872 -0.3536,0.13088 -28.99521,4.88871 -63.64802,10.57296 -34.65281,5.68424 -63.72839,10.47833 -64.61239,10.65353 -1.3859,0.27467 -3.11163,-1.18855 -12.52964,-10.62371 z" + id="path3075" + transform="scale(0.26458333)" /> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" + x="48.989689" + y="16.670103" + id="text6475"><tspan + sodipodi:role="line" + id="tspan6473" + style="stroke-width:0.264583" + x="48.989689" + y="16.670103"></tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" + x="50.474586" + y="25.95421" + id="text29322"><tspan + sodipodi:role="line" + id="tspan29320" + style="stroke-width:0.264583" + x="50.474586" + y="25.95421">N</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" + x="51.019772" + y="131.41812" + id="text33982"><tspan + sodipodi:role="line" + id="tspan33980" + style="stroke-width:0.264583" + x="51.019772" + y="131.41812">S</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" + x="104.54184" + y="78.702988" + id="text37802"><tspan + sodipodi:role="line" + id="tspan37800" + style="stroke-width:0.264583" + x="104.54184" + y="78.702988">E</tspan></text> + <text + xml:space="preserve" + style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" + x="-4.1540327" + y="78.702988" + id="text39852"><tspan + sodipodi:role="line" + id="tspan39850" + style="stroke-width:0.264583" + x="-4.1540327" + y="78.702988">W</tspan></text> + </g> +</svg> diff --git a/examples/sensors/sensorsshowcase/images/magnet.svg b/examples/sensors/sensorsshowcase/images/magnet.svg new file mode 100644 index 00000000..21d9f46b --- /dev/null +++ b/examples/sensors/sensorsshowcase/images/magnet.svg @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + width="152.6804mm" + height="186.70102mm" + viewBox="0 0 152.6804 186.70102" + version="1.1" + id="svg22292" + sodipodi:docname="magnet.svg" + inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <sodipodi:namedview + id="namedview22294" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + inkscape:document-units="mm" + showgrid="false" + inkscape:zoom="3.1108586" + inkscape:cx="384.62051" + inkscape:cy="214.24953" + inkscape:window-width="2560" + inkscape:window-height="1377" + inkscape:window-x="1912" + inkscape:window-y="72" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" /> + <defs + id="defs22289" /> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0.34020391,-51.711357)"> + <path + style="fill:none;stroke:#0000ff;stroke-width:40;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path22661" + sodipodi:type="arc" + sodipodi:cx="76.206184" + sodipodi:cy="162.27835" + sodipodi:rx="56.134018" + sodipodi:ry="56.134018" + sodipodi:start="1.5707963" + sodipodi:end="3.1415927" + sodipodi:arc-type="arc" + d="M 76.206184,218.41237 A 56.134018,56.134018 0 0 1 36.513439,201.9711 56.134018,56.134018 0 0 1 20.072166,162.27835" + sodipodi:open="true" /> + <rect + style="fill:#cccccc;fill-opacity:1;stroke:none;stroke-width:0.814709;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect22976" + width="39.829895" + height="50.35051" + x="0.17010537" + y="51.711357" /> + <path + style="fill:#ff0000;stroke:#ff0000;stroke-width:40;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path23734" + sodipodi:type="arc" + sodipodi:cx="-76.206184" + sodipodi:cy="162.27835" + sodipodi:rx="56.134018" + sodipodi:ry="56.134018" + sodipodi:start="1.5707963" + sodipodi:end="3.1415927" + sodipodi:arc-type="arc" + d="M -76.206184,218.41237 A 56.134018,56.134018 0 0 1 -115.89893,201.9711 56.134018,56.134018 0 0 1 -132.3402,162.27835" + sodipodi:open="true" + transform="scale(-1,1)" /> + <rect + style="fill:#cccccc;fill-opacity:1;stroke:none;stroke-width:0.816447;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect24456" + width="40" + height="50.35051" + x="112.26804" + y="51.711357" /> + <rect + style="fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:1.00283;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect24480" + width="40" + height="60.340206" + x="112.26804" + y="102.06187" /> + <rect + style="fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:1.00563;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="rect24580" + width="39.829895" + height="60.93557" + x="0.17010537" + y="102.06187" /> + </g> +</svg> diff --git a/examples/sensors/sensorsshowcase/images/qt_logo.png b/examples/sensors/sensorsshowcase/images/qt_logo.png Binary files differnew file mode 100644 index 00000000..3a75e10c --- /dev/null +++ b/examples/sensors/sensorsshowcase/images/qt_logo.png diff --git a/examples/sensors/sensorsshowcase/main.cpp b/examples/sensors/sensorsshowcase/main.cpp new file mode 100644 index 00000000..4a7bd285 --- /dev/null +++ b/examples/sensors/sensorsshowcase/main.cpp @@ -0,0 +1,18 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +#include <QGuiApplication> +#include <QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc,argv); + QGuiApplication::setOrganizationName("QtProject"); + QGuiApplication::setApplicationName("Sensors Showcase"); + + QQmlApplicationEngine engine; + engine.loadFromModule("SensorShowcaseModule", "Main"); + if (engine.rootObjects().isEmpty()) + return -1; + + return app.exec(); +} diff --git a/examples/sensors/sensorsshowcase/qmldir b/examples/sensors/sensorsshowcase/qmldir new file mode 100644 index 00000000..76e61cdf --- /dev/null +++ b/examples/sensors/sensorsshowcase/qmldir @@ -0,0 +1,9 @@ +module SensorShowcaseModule +prefer :/qt/qml/SensorShowcaseModule/ +Main 1.0 Main.qml +Accelerometer 1.0 Accelerometer.qml +Compass 1.0 Compass.qml +Gyroscope 1.0 Gyroscope.qml +Magnetometer 1.0 Magnetometer.qml +Proximity 1.0 Proximity.qml +ProgressXYZBar 1.0 ProgressXYZBar.qml diff --git a/examples/sensors/sensorsshowcase/qtquickcontrols2.conf b/examples/sensors/sensorsshowcase/qtquickcontrols2.conf new file mode 100644 index 00000000..76439328 --- /dev/null +++ b/examples/sensors/sensorsshowcase/qtquickcontrols2.conf @@ -0,0 +1,6 @@ +[Controls] +Style=Material + +[Material] +Background=#eafcf3 +Accent=#28c878 diff --git a/examples/sensors/sensorsshowcase/sensorsshowcase.pro b/examples/sensors/sensorsshowcase/sensorsshowcase.pro new file mode 100644 index 00000000..cded9071 --- /dev/null +++ b/examples/sensors/sensorsshowcase/sensorsshowcase.pro @@ -0,0 +1,46 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +QT += quick sensors svg + +TARGET = sensorsshowcase +TEMPLATE = app + +SOURCES = main.cpp + +qml_resources.files = \ + qmldir \ + Main.qml \ + Accelerometer.qml \ + Compass.qml \ + Gyroscope.qml \ + Magnetometer.qml \ + Proximity.qml \ + ProgressXYZBar.qml \ + images/compass.svg \ + images/magnet.svg \ + images/qt_logo.png + +qml_resources.prefix = /qt/qml/SensorShowcaseModule + +data_resources.files = \ + qtquickcontrols2.conf + +data_resources.prefix = / + +RESOURCES += \ + qml_resources \ + data_resources + +android { + OTHER_FILES = android/AndroidManifest.xml + ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android +} + +ios { + QMAKE_INFO_PLIST = Info.plist + EXAMPLE_FILES += Info.plist +} + +target.path = $$[QT_INSTALL_EXAMPLES]/sensors/sensorsshowcase +INSTALLS += target diff --git a/examples/sensors/sensorsshowcase/sensorsupport.h b/examples/sensors/sensorsshowcase/sensorsupport.h new file mode 100644 index 00000000..915157f8 --- /dev/null +++ b/examples/sensors/sensorsshowcase/sensorsupport.h @@ -0,0 +1,41 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +#ifndef SENSORSUPPORT_H +#define SENSORSUPPORT_H + +#include <QObject> +#include <QtQmlIntegration> +#include <QtSensors/QtSensors> + +class SensorSupport : public QObject +{ + Q_OBJECT + QML_ELEMENT + QML_SINGLETON + QML_UNCREATABLE("SensorSupport is a utility class") +public: + explicit SensorSupport(QObject *parent = nullptr) : QObject(parent) { } + + Q_INVOKABLE static bool hasAccelerometer() + { + return !QSensor::sensorsForType(QAccelerometer::sensorType).empty(); + } + Q_INVOKABLE static bool hasCompass() + { + return !QSensor::sensorsForType(QCompass::sensorType).empty(); + } + Q_INVOKABLE static bool hasGyroscope() + { + return !QSensor::sensorsForType(QGyroscope::sensorType).empty(); + } + Q_INVOKABLE static bool hasMagnetometer() + { + return !QSensor::sensorsForType(QMagnetometer::sensorType).empty(); + } + Q_INVOKABLE static bool hasProximity() + { + return !QSensor::sensorsForType(QProximitySensor::sensorType).empty(); + } +}; + +#endif // SENSORSUPPORT_H |