Commit e2aa2594 authored by David Boddie's avatar David Boddie

Merge branch 'add-proximity-example' into 'master'

Add documentation for the Proximity example

See merge request !394
parents 8297e6f6 63ec7654
Pipeline #53007 passed with stages
in 2 minutes and 31 seconds
......@@ -34,3 +34,6 @@
[submodule "Apps/Examples/Sensors/Ambient_Light/app"]
path = Apps/Examples/Sensors/Ambient_Light/app
url =
[submodule "Apps/Examples/Sensors/Proximity/app"]
path = Apps/Examples/Sensors/Proximity/app
url =
.. |main-file| replace:: ````
.. |executable| replace:: ``proximity``
.. |desktop-entry-in| replace:: ````
.. |desktop-entry| replace:: ``com.example.proximity.desktop``
.. |desktop-entry-ref| replace:: desktop entry file
.. |svg-file| replace:: ``com.example.proximity.svg``
.. include:: /Apps/Examples/common/Building_the_App.txt
.. |project| replace::
.. |repo| replace:: proximity.git
.. |project-repo| replace:: ````
.. include:: /Apps/Examples/common/Getting_the_App.txt
.. |manifest| replace:: ``com.example.proximity.json``
.. |manifest-path| replace:: app/com.example.proximity.json
.. |app-id| replace:: com.example.proximity
.. |extra-permissions-info| replace:: We also specify the ``--system-talk-name=net.hadess.SensorProxy`` permission to request access to the `iio-sensor-proxy`_ service, using the mechanism described in the :ref:`flatpak_app_permissions_guide` guide.
.. |meson-app-module| replace:: proximity
.. |extra-module-info| replace:: The application's module is usually the last in the list:
.. include:: ../../common/Packaging_the_App.txt
.. include:: /links.txt
.. _Sensors_Proximity_example_src:
Source Files
Most of the code for the application is included in a single ```` file which contains an ``Application`` class to manage the running of the application and a ``Window`` class to describe the user interface.
.. contents::
Much of the code is very similar to other examples and tutorials. We will focus on the parts that are specific to this example.
Relevant Modules
In addition to the usual modules for accessing command line arguments and GTK widgets, we use a custom ``sensor`` module to enable us to access the sensors.
.. literalinclude:: app/src/
:language: python3
:start-at: import sys
:end-at: from gi.repository
The ``sensor`` module is described in more detail `below <Sensors_Proximity_example_proximity_>`_.
Setting up the Application
The application provides an ``Application`` class with the usual methods to set up the application and perform tasks when it is run. In the ``__init__`` method we set up the application title, ID and program name to ensure that it integrates into the environment:
.. literalinclude:: app/src/
:language: python3
:start-at: class Application
:end-at: set_prgname
In the ``do_activate`` method, we create the application window and show it, but we also create a ``Proximity`` object from the ``sensor`` module:
.. literalinclude:: app/src/
:language: python3
:start-at: def do_activate
:end-at: claim()
The ``Proximity`` object has a ``changed`` signal that we connect to the window's ``update_info`` method.
The ``do_shutdown`` method of the application is called just before the application exits. In this method we call the ``release`` method of the ``Proximity`` object to release the sensor for other applications:
.. literalinclude:: app/src/
:language: python3
:start-at: def do_shutdown
:end-at: release()
Applications should usually only claim the sensor when required and release it as soon as possible.
Creating the User Interface
The ``Window`` class is used to display a simple user interface that updates when new sensor data is available. We begin by a `Gtk.Label`_ widget to show the status of the sensor:
.. literalinclude:: app/src/
:language: python3
:start-at: class Window
:end-at: self.add
The label will be updated when the sensor's state changes due to the signal connection in the application's ``do_activate`` method.
Responding to Updates
As described above, the application contains a ``Proximity`` object that will emit a ``changed`` signal when the sensor's state changes. When this occurs the ``update_info`` method is called:
.. literalinclude:: app/src/
:language: python3
:start-at: def update_info
:end-at: Far
The signal delivers two values in the ``sensor`` and ``near`` parameters of the method. Since there is only one ``proximity`` object in use, we simply check the value of ``near`` to determine which string to show in the label.
The information provided by the ``changed`` signal is intended to be simple, so that the GUI part of the application only needs to include code to respond to proximity sensor changes. The ``Proximity`` class hides any complexity from the main application.
.. _Sensors_Proximity_example_proximity:
The Proximity Class
The ``sensor`` module provides the ``Proximity`` class that is used to access sensor data, using the ``Gio`` module to communicate with a D-Bus service:
.. literalinclude:: app/src/
:language: python3
:start-at: import gi
:end-at: gi.repository
Since the ``Proximity`` class needs to emit signals, the ``GObject`` class from the ``GObject`` module is also needed. The class is derived from ``GObject`` and declares the ``changed`` signal to inform the rest of the application about sensor changes:
.. literalinclude:: app/src/
:language: python3
:start-at: class Proximity
:end-at: }
In the ``__init__`` method of the class, we call the base class's ``__init__`` method to properly initialize it, before creating a proxy object that communicates with the ``net.hadess.SensorProxy`` service on the system D-Bus:
.. literalinclude:: app/src/
:language: python3
:start-at: def __init__
:end-at: self.properties_changed, None)
This proxy object emits the ``g-properties-changed`` signal when any of the properties exposed by the service change. We connect this signal to the ``properties_changed`` method in this class:
.. literalinclude:: app/src/
:language: python3
:start-at: def properties_changed
:end-at: self.emit
In the ``properties_changed`` method, we respond to changes from the D-Bus service by reading the state of the proximity sensor and emitting the ``changed`` signal. This provides only the basic information to any methods that receive it, keeping the details of the D-Bus communication separate from other components.
We also provide the ``claim`` and ``release`` methods to allow the application to start and stop using the sensor. Each of these methods check for the presence of the proximity sensor by reading the `HasProximity <net.hadess.SensorProxy.HasProximity_>`_ property of the D-Bus service:
.. literalinclude:: app/src/
:language: python3
:start-at: def claim
:end-at: None)
In the ``claim`` method, we call the `ClaimProximity <net.hadess.SensorProxy.ClaimProximity_>`_ method if the sensor is available.
.. literalinclude:: app/src/
:language: python3
:start-at: def release
:end-at: None)
In the ``release`` method, we call the `ReleaseProximity <net.hadess.SensorProxy.ClaimProximity_>`_ method to release it for other applications.
Handling sensor data involves requesting information from the ``net.hadess.SensorProxy`` service on the system D-Bus. We create a module containing the ``Proximity`` class to communicate with the service, allowing the main application to subscribe to sensor changes by connecting to a ``changed`` signal.
The ``Proximity`` class itself performs a few tasks to make this possible, but users of this class can simply
* connect its ``changed`` signal to a callback method,
* call its ``claim`` method to start receiving updates, and
* call its ``release`` method to stop receiving updates.
Applications do not need to provide an abstraction like this one, but it can make it easier to separate sensor-handling code from GUI code.
.. include:: /links.txt
.. _examples_Sensors_Proximity_summary:
Applications can access the proximity sensor by using the `DBusProxy`_ class from the ``Gio`` module to talk to a D-Bus service. The API provided by the service can also be used to access other sensors.
It can be useful to wrap the communication code in a separate class and use its API from GUI code. This example includes a simple class that performs this task.
When distributed as a flatpak, the manifest needs to include the ``--system-talk-name=net.hadess.SensorProxy`` permission that allows the application to access the ``net.hadess.SensorProxy`` service on the system D-Bus.
.. include:: /links.txt
Subproject commit b9ee82302bf51c51fdeb4ff669a8c666c518a909
.. _examples_Sensors_Proximity:
This example demonstrates a way to read values from the proximity sensor. When run, the application shows whether objects are near to the proximity sensor.
.. image:: images/screenshot.png
:scale: 50%
:align: center
:alt: A screenshot of the application running in the phone environment
In :ref:`Sensors_Proximity_example_src` we focus on the parts of the application that handle access to the proximity sensor.
.. toctree::
:maxdepth: 1
.. include:: /links.txt
......@@ -24,6 +24,7 @@ information about the APIs used by applications.
......@@ -151,6 +151,12 @@
.. _`net.hadess.SensorProxy.HasAmbientLight`:
.. _`net.hadess.SensorProxy.LightLevel`:
.. _`net.hadess.SensorProxy.LightLevelUnit`:
.. _`net.hadess.SensorProxy.ClaimProximity`:
.. _`net.hadess.SensorProxy.HasAmbientLight`:
.. _`net.hadess.SensorProxy.HasProximity`:
.. _`net.hadess.SensorProxy.LightLevel`:
.. _`net.hadess.SensorProxy.LightLevelUnit`:
.. _`net.hadess.SensorProxy.ReleaseProximity`:
.. _`net.hadess.SensorProxy.ReleaseLight`:
.. _`Nightly GNOME Apps`:
.. _`Ninja`:
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment