summaryrefslogtreecommitdiffstats
path: root/tests/manual/sensor_explorer_widgets
diff options
context:
space:
mode:
Diffstat (limited to 'tests/manual/sensor_explorer_widgets')
-rw-r--r--tests/manual/sensor_explorer_widgets/CMakeLists.txt18
-rw-r--r--tests/manual/sensor_explorer_widgets/explorer.cpp406
-rw-r--r--tests/manual/sensor_explorer_widgets/explorer.h47
-rw-r--r--tests/manual/sensor_explorer_widgets/explorer.ui406
-rw-r--r--tests/manual/sensor_explorer_widgets/main.cpp13
5 files changed, 890 insertions, 0 deletions
diff --git a/tests/manual/sensor_explorer_widgets/CMakeLists.txt b/tests/manual/sensor_explorer_widgets/CMakeLists.txt
new file mode 100644
index 00000000..357eb02e
--- /dev/null
+++ b/tests/manual/sensor_explorer_widgets/CMakeLists.txt
@@ -0,0 +1,18 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## sensor_explorer Binary:
+#####################################################################
+
+qt_internal_add_manual_test(tst_manual_sensor_explorer_widgets
+ GUI
+ SOURCES
+ explorer.cpp explorer.h explorer.ui
+ main.cpp
+ LIBRARIES
+ Qt::Sensors
+ Qt::Widgets
+ ENABLE_AUTOGEN_TOOLS
+ uic
+)
diff --git a/tests/manual/sensor_explorer_widgets/explorer.cpp b/tests/manual/sensor_explorer_widgets/explorer.cpp
new file mode 100644
index 00000000..e6353c01
--- /dev/null
+++ b/tests/manual/sensor_explorer_widgets/explorer.cpp
@@ -0,0 +1,406 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "explorer.h"
+#include <QTimer>
+#include <QDebug>
+#include <qsensor.h>
+#include <QMetaObject>
+#include <QMetaProperty>
+
+Explorer::Explorer(QWidget *parent)
+ : QMainWindow(parent)
+ , m_sensor(0)
+ , ignoreItemChanged(false)
+{
+ ui.setupUi(this);
+ // Clear out example data from the .ui file
+ ui.sensors->clear();
+ clearSensorProperties();
+ clearReading();
+
+ // Force types to be registered
+ (void)QSensor::sensorTypes();
+ // Listen for changes to the registered types
+ QSensor *sensor = new QSensor(QByteArray(), this);
+ connect(sensor, SIGNAL(availableSensorsChanged()), this, SLOT(loadSensors()));
+}
+
+Explorer::~Explorer()
+{
+}
+
+void Explorer::loadSensors()
+{
+ qDebug() << "Explorer::loadSensors";
+
+ // Clear out anything that's in there now
+ ui.sensors->clear();
+
+ for (const QByteArray &type : QSensor::sensorTypes()) {
+ qDebug() << "Found type" << type;
+ for (const QByteArray &identifier : QSensor::sensorsForType(type)) {
+ qDebug() << "Found identifier" << identifier;
+ // Don't put in sensors we can't connect to
+ QSensor sensor(type);
+ sensor.setIdentifier(identifier);
+ if (!sensor.connectToBackend()) {
+ qDebug() << "Couldn't connect to" << identifier;
+ continue;
+ }
+
+ qDebug() << "Adding identifier" << identifier;
+ QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << QString::fromLatin1(identifier));
+ item->setData(0, Qt::UserRole, QString::fromLatin1(type));
+ ui.sensors->addTopLevelItem(item);
+ }
+ }
+
+ if (ui.sensors->topLevelItemCount() == 0) {
+ QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() << tr("No Sensors Found"));
+ item->setData(0, Qt::UserRole, QString());
+ ui.sensors->addTopLevelItem(item);
+ }
+
+ ui.sensors->setCurrentItem(0);
+ ui.scrollArea->hide();
+
+ resizeSensors();
+}
+
+void Explorer::resizeSensors()
+{
+ ui.sensors->resizeColumnToContents(0);
+ int length = ui.sensors->header()->length() + 4;
+ ui.sensors->setFixedWidth(length);
+}
+
+void Explorer::on_sensors_currentItemChanged()
+{
+ qDebug() << "Explorer::sensorSelected";
+
+ // Clear out anything that's in there now
+ if (m_sensor) {
+ delete m_sensor;
+ m_sensor = 0;
+ }
+ clearSensorProperties();
+ clearReading();
+ ui.scrollArea->hide();
+
+ // Check that we've selected an item
+ QTreeWidgetItem *item = ui.sensors->currentItem();
+ if (!item) {
+ qWarning() << "Didn't select an item!";
+ return;
+ }
+
+ QByteArray type = item->data(0, Qt::UserRole).toString().toLatin1();
+ QByteArray identifier = item->data(0, Qt::DisplayRole).toString().toLatin1();
+
+ if (type.isEmpty()) {
+ // Uh oh, there aren't any sensors.
+ // The user has clicked the dummy list entry so just ignore it.
+ return;
+ }
+
+ // Connect to the sensor so we can probe it
+ m_sensor = new QSensor(type, this);
+ connect(m_sensor, SIGNAL(readingChanged()), this, SLOT(sensor_changed()));
+ m_sensor->setIdentifier(identifier);
+ if (!m_sensor->connectToBackend()) {
+ delete m_sensor;
+ m_sensor = 0;
+ qWarning() << "Can't connect to the sensor!";
+ return;
+ }
+
+ ui.scrollArea->show();
+ loadSensorProperties();
+ loadReading();
+
+ adjustTableColumns(ui.sensorprops);
+ adjustTableColumns(ui.reading);
+ QTimer::singleShot(100, this, SLOT(adjustSizes()));
+}
+
+void Explorer::clearReading()
+{
+ ui.reading->setRowCount(0);
+}
+
+void Explorer::loadReading()
+{
+ // Probe the reading using Qt's meta-object facilities
+ QSensorReading *reading = m_sensor->reading();
+ if (!reading)
+ return;
+ const QMetaObject *mo = reading->metaObject();
+ int firstProperty = QSensorReading::staticMetaObject.propertyOffset();
+
+ ui.reading->setRowCount(mo->propertyCount() - firstProperty);
+
+ for (int i = firstProperty; i < mo->propertyCount(); ++i) {
+ int row = i - firstProperty;
+ QTableWidgetItem *index;
+ if (row == 0)
+ // timestamp is not available via index
+ index = new QTableWidgetItem(QLatin1String("N/A"));
+ else
+ index = new QTableWidgetItem(QVariant(row - 1).toString());
+ QTableWidgetItem *prop = new QTableWidgetItem(mo->property(i).name());
+ QString typeName = QLatin1String(mo->property(i).typeName());
+ int delimiter = typeName.lastIndexOf("::");
+ if (delimiter != -1)
+ typeName = typeName.mid(delimiter + 2);
+ QTableWidgetItem *type = new QTableWidgetItem(typeName);
+ QTableWidgetItem *value = new QTableWidgetItem();
+
+ index->setFlags(value->flags() ^ Qt::ItemIsEditable);
+ prop->setFlags(value->flags() ^ Qt::ItemIsEditable);
+ type->setFlags(value->flags() ^ Qt::ItemIsEditable);
+ value->setFlags(value->flags() ^ Qt::ItemIsEditable);
+
+ ui.reading->setItem(row, 0, index);
+ ui.reading->setItem(row, 1, prop);
+ ui.reading->setItem(row, 2, type);
+ ui.reading->setItem(row, 3, value);
+ }
+}
+
+void Explorer::clearSensorProperties()
+{
+ ui.sensorprops->setRowCount(0);
+}
+
+void Explorer::loadSensorProperties()
+{
+ ignoreItemChanged = true;
+
+ // Probe the sensor using Qt's meta-object facilities
+ const QMetaObject *mo = m_sensor->metaObject();
+ int firstProperty = QSensor::staticMetaObject.propertyOffset();
+
+ int rows = mo->propertyCount() - firstProperty;
+ ui.sensorprops->setRowCount(rows);
+
+ int offset = 0;
+ for (int i = firstProperty; i < mo->propertyCount(); ++i) {
+ int row = i - firstProperty - offset;
+ QLatin1String name(mo->property(i).name());
+ if (name == "identifier" ||
+ //name == "type" ||
+ name == "reading" ||
+ name == "connected" ||
+ name == "running" ||
+ name == "supportsPolling") {
+ ++offset;
+ continue;
+ }
+ QTableWidgetItem *prop = new QTableWidgetItem(name);
+ QString typeName = QLatin1String(mo->property(i).typeName());
+ int delimiter = typeName.lastIndexOf("::");
+ if (delimiter != -1)
+ typeName = typeName.mid(delimiter + 2);
+ QTableWidgetItem *type = new QTableWidgetItem(typeName);
+ QVariant v = mo->property(i).read(m_sensor);
+ QString val;
+ if (typeName == "qrangelist") {
+ qrangelist rl = v.value<qrangelist>();
+ QStringList out;
+ for (const qrange &r : rl) {
+ if (r.first == r.second)
+ out << QString("%1 Hz").arg(r.first);
+ else
+ out << QString("%1-%2 Hz").arg(r.first).arg(r.second);
+ }
+ val = out.join(", ");
+ } else if (typeName == "qoutputrangelist") {
+ qoutputrangelist rl = v.value<qoutputrangelist>();
+ QStringList out;
+ for (const qoutputrange &r : rl)
+ out << QString("(%1, %2) += %3").arg(r.minimum).arg(r.maximum).arg(r.accuracy);
+ val = out.join(", ");
+ } else {
+ val = v.toString();
+ }
+ QTableWidgetItem *value = new QTableWidgetItem(val);
+
+ prop->setFlags(value->flags() ^ Qt::ItemIsEditable);
+ type->setFlags(value->flags() ^ Qt::ItemIsEditable);
+ if (!mo->property(i).isWritable()) {
+ // clear the editable flag
+ value->setFlags(value->flags() ^ Qt::ItemIsEditable);
+ }
+
+ ui.sensorprops->setItem(row, 0, prop);
+ ui.sensorprops->setItem(row, 1, type);
+ ui.sensorprops->setItem(row, 2, value);
+ }
+
+ // We don't add all properties
+ ui.sensorprops->setRowCount(rows - offset);
+
+ ignoreItemChanged = false;
+}
+
+void Explorer::showEvent(QShowEvent *event)
+{
+ // Once we're visible, load the sensors
+ // (don't delay showing the UI while we load plugins, connect to backends, etc.)
+ QTimer::singleShot(0, this, SLOT(loadSensors()));
+
+ QMainWindow::showEvent(event);
+}
+
+// Resize columns to fit the space.
+// This shouldn't be so hard!
+void Explorer::adjustTableColumns(QTableWidget *table)
+{
+ if (table->rowCount() == 0) {
+ table->setFixedHeight(0);
+ return;
+ }
+
+ // At least this is easy to do
+ table->resizeColumnsToContents();
+ int length = table->verticalHeader()->length();
+ length += (length / static_cast<qreal>(table->verticalHeader()->count())); // Add 1 more (the header itself)
+ table->setFixedHeight(length);
+
+ int columns = table->columnCount();
+ QList<int> width;
+ int suggestedWidth = 0;
+ for (int i = 0; i < columns; ++i) {
+ int cwidth = table->columnWidth(i);
+ width << cwidth;
+ suggestedWidth += cwidth;
+ }
+
+ int actualWidth = table->size().width();
+ //qDebug() << "suggestedWidth" << suggestedWidth << "actualWidth" << actualWidth;
+
+ // We only scale the columns up, we don't scale down
+ if (actualWidth <= suggestedWidth)
+ return;
+
+ qreal multiplier = actualWidth / static_cast<qreal>(suggestedWidth);
+ int currentSpace = 4;
+ for (int i = 0; i < columns; ++i) {
+ width[i] = multiplier * width[i];
+ currentSpace += width[i];
+ }
+
+ // It ends up too big due to cell decorations or something.
+ // Make things smaller one pixel at a time in round robin fashion until we're good.
+ int i = 0;
+ while (currentSpace > actualWidth) {
+ --width[i];
+ --currentSpace;
+ i = (i + 1) % columns;
+ }
+
+ for (int i = 0; i < columns; ++i) {
+ table->setColumnWidth(i, width[i]);
+ }
+
+ table->setMinimumWidth(suggestedWidth);
+}
+
+void Explorer::adjustSizes()
+{
+ adjustTableColumns(ui.reading);
+ adjustTableColumns(ui.sensorprops);
+}
+
+void Explorer::resizeEvent(QResizeEvent *event)
+{
+ resizeSensors();
+ adjustSizes();
+
+ QMainWindow::resizeEvent(event);
+}
+
+void Explorer::on_start_clicked()
+{
+ m_sensor->start();
+ QTimer::singleShot(0, this, SLOT(loadSensorProperties()));
+}
+
+void Explorer::on_stop_clicked()
+{
+ m_sensor->stop();
+ QTimer::singleShot(0, this, SLOT(loadSensorProperties()));
+}
+
+void Explorer::sensor_changed()
+{
+ QSensorReading *reading = m_sensor->reading();
+ filter(reading);
+}
+
+bool Explorer::filter(QSensorReading *reading)
+{
+ const QMetaObject *mo = reading->metaObject();
+ int firstProperty = QSensorReading::staticMetaObject.propertyOffset();
+
+ for (int i = firstProperty; i < mo->propertyCount(); ++i) {
+ int row = i - firstProperty;
+ QString typeName = QLatin1String(mo->property(i).typeName());
+ int delimiter = typeName.lastIndexOf("::");
+ if (delimiter != -1)
+ typeName = typeName.mid(delimiter + 2);
+ QLatin1String name(mo->property(i).name());
+ QTableWidgetItem *value = ui.reading->item(row, 3);
+ QVariant val = mo->property(i).read(reading);
+ if (typeName == "LightLevel") {
+ QString text;
+ switch (val.toInt()) {
+ case 1:
+ text = "Dark";
+ break;
+ case 2:
+ text = "Twilight";
+ break;
+ case 3:
+ text = "Light";
+ break;
+ case 4:
+ text = "Bright";
+ break;
+ case 5:
+ text = "Sunny";
+ break;
+ default:
+ text = "Undefined";
+ break;
+ }
+ value->setText(text);
+ } else {
+ value->setText(val.toString());
+ }
+ }
+
+ adjustTableColumns(ui.reading);
+ //QTimer::singleShot(0, this, SLOT(adjustSizes()));
+
+ return false;
+}
+
+void Explorer::on_sensorprops_itemChanged(QTableWidgetItem *item)
+{
+ if (ignoreItemChanged)
+ return;
+ if (!(item->flags() & Qt::ItemIsEditable))
+ return;
+
+ int row = item->row();
+ QString name = ui.sensorprops->item(row, 0)->text();
+ QVariant value = item->text();
+
+ qDebug() << "setProperty" << name << value;
+ m_sensor->setProperty(name.toLatin1().constData(), QVariant(value));
+
+ QTimer::singleShot(0, this, SLOT(loadSensorProperties()));
+}
+
diff --git a/tests/manual/sensor_explorer_widgets/explorer.h b/tests/manual/sensor_explorer_widgets/explorer.h
new file mode 100644
index 00000000..92aa6f47
--- /dev/null
+++ b/tests/manual/sensor_explorer_widgets/explorer.h
@@ -0,0 +1,47 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef EXPLORER_H
+#define EXPLORER_H
+
+#include <QMainWindow>
+#include <ui_explorer.h>
+#include <qsensor.h>
+
+
+class Explorer : public QMainWindow, public QSensorFilter
+{
+ Q_OBJECT
+public:
+ Explorer(QWidget *parent = 0);
+ ~Explorer();
+
+ bool filter(QSensorReading *reading) override;
+
+private slots:
+ void loadSensors();
+ void on_sensors_currentItemChanged();
+ void on_sensorprops_itemChanged(QTableWidgetItem *item);
+ void on_start_clicked();
+ void on_stop_clicked();
+ void sensor_changed();
+ void adjustSizes();
+ void loadSensorProperties();
+
+private:
+ void showEvent(QShowEvent *event) override;
+ void resizeEvent(QResizeEvent *event) override;
+
+ void clearReading();
+ void loadReading();
+ void clearSensorProperties();
+ void adjustTableColumns(QTableWidget *table);
+ void resizeSensors();
+
+ Ui::Explorer ui;
+ QSensor *m_sensor;
+ bool ignoreItemChanged;
+};
+
+#endif
+
diff --git a/tests/manual/sensor_explorer_widgets/explorer.ui b/tests/manual/sensor_explorer_widgets/explorer.ui
new file mode 100644
index 00000000..166e9c36
--- /dev/null
+++ b/tests/manual/sensor_explorer_widgets/explorer.ui
@@ -0,0 +1,406 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Explorer</class>
+ <widget class="QMainWindow" name="Explorer">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>760</width>
+ <height>636</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralwidget">
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <property name="spacing">
+ <number>9</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Sensors that were detected on the device are listed in the list on the left, grouped by type. The reading properties for the sensor will be presented on the right.</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::AutoText</enum>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" name="widget" native="true">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>9</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QWidget" name="widget_2" native="true">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="spacing">
+ <number>9</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Sensor</string>
+ </property>
+ <property name="buddy">
+ <cstring>sensors</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTreeWidget" name="sensors">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ <property name="rootIsDecorated">
+ <bool>false</bool>
+ </property>
+ <property name="itemsExpandable">
+ <bool>false</bool>
+ </property>
+ <property name="expandsOnDoubleClick">
+ <bool>false</bool>
+ </property>
+ <attribute name="headerVisible">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="headerVisible">
+ <bool>false</bool>
+ </attribute>
+ <column>
+ <property name="text">
+ <string notr="true">Sensor</string>
+ </property>
+ </column>
+ <item>
+ <property name="text">
+ <string notr="true">dummy.accelerometer</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QScrollArea" name="scrollArea">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>477</width>
+ <height>556</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <property name="spacing">
+ <number>9</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QWidget" name="widget_4" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="spacing">
+ <number>9</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Sensor Properties</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTableWidget" name="sensorprops">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="columnCount">
+ <number>3</number>
+ </property>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ <row>
+ <property name="text">
+ <string notr="true">1</string>
+ </property>
+ </row>
+ <column>
+ <property name="text">
+ <string>Name</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Type</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Value</string>
+ </property>
+ </column>
+ <item row="0" column="0">
+ <property name="text">
+ <string notr="true">supportedIntervals</string>
+ </property>
+ </item>
+ <item row="0" column="1">
+ <property name="text">
+ <string notr="true">qrangelist</string>
+ </property>
+ </item>
+ <item row="0" column="2">
+ <property name="text">
+ <string/>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" name="widget_3" native="true">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>9</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="start">
+ <property name="text">
+ <string>start</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="stop">
+ <property name="text">
+ <string>stop</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" name="widget_5" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="spacing">
+ <number>9</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Reading Properties</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTableWidget" name="reading">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="columnCount">
+ <number>4</number>
+ </property>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ <row>
+ <property name="text">
+ <string notr="true">1</string>
+ </property>
+ </row>
+ <row>
+ <property name="text">
+ <string notr="true">2</string>
+ </property>
+ </row>
+ <column>
+ <property name="text">
+ <string>Index</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Value</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Type</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Value</string>
+ </property>
+ </column>
+ <item row="0" column="0">
+ <property name="text">
+ <string notr="true">0</string>
+ </property>
+ </item>
+ <item row="0" column="1">
+ <property name="text">
+ <string notr="true">x</string>
+ </property>
+ </item>
+ <item row="0" column="2">
+ <property name="text">
+ <string notr="true">qreal</string>
+ </property>
+ </item>
+ <item row="0" column="3">
+ <property name="text">
+ <string>9.8</string>
+ </property>
+ </item>
+ <item row="1" column="0">
+ <property name="text">
+ <string notr="true">0</string>
+ </property>
+ </item>
+ <item row="1" column="1">
+ <property name="text">
+ <string notr="true">changeOfBeingEaten</string>
+ </property>
+ </item>
+ <item row="1" column="2">
+ <property name="text">
+ <string notr="true">bool</string>
+ </property>
+ </item>
+ <item row="1" column="3">
+ <property name="text">
+ <string>true</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>0</width>
+ <height>18</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QStatusBar" name="statusbar"/>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/manual/sensor_explorer_widgets/main.cpp b/tests/manual/sensor_explorer_widgets/main.cpp
new file mode 100644
index 00000000..0e2ea93d
--- /dev/null
+++ b/tests/manual/sensor_explorer_widgets/main.cpp
@@ -0,0 +1,13 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "explorer.h"
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ Explorer explorer;
+ explorer.show();
+ return app.exec();
+}
+