Commit 8661527b authored by David Boddie's avatar David Boddie 💬
Browse files

Tidy up code description, add a summary to pictures example

parent 130f90d8
Pipeline #5521 failed with stage
in 47 seconds
.. |manifest| replace:: ``com.example.pictures.json``
.. |manifest-path| replace:: app/com.example.pictures.json
.. |app-id| replace:: com.example.pictures
.. |extra-permissions-info| replace:: We also specify the ``--filesystem=xdg-pictures`` permission to request access to the user's *Pictures* directory, as described in the :ref:`flatpak_app_permissions_guide` guide.
.. include:: ../../common/Packaging_the_App.txt
......@@ -6,12 +6,7 @@ Source Files
.. contents::
:local:
The main source code for the application can be found in the ``main.py`` file within the ``src`` directory. The purpose of the other files is explained in other tutorials, such as the :ref:`First_Application` tutorial.
The Program
-----------
Most the code for the application is included in a single ``main.py`` file which contains a single ``Application`` class to manage the running of the application and a ``main`` function to start it.
Most of the code for the application is included in a single ``main.py`` file which contains a single ``Application`` class to manage the running of the application and a ``main`` function to start it.
Much of the is very similar to other examples and tutorials. We will focus on the parts that are specific to this example.
......@@ -42,23 +37,32 @@ In the ``do_startup`` method we define two parameters for the thumbnail dimensio
These are hard-coded in this example, but more complex applications would load these values from the application's settings.
In the ``do_activate`` method we set up the user interface, using a helper class to set up an adaptive user interface consisting of two leaflets: one in the window's header bar; the other in the main area of the window:
In the ``do_activate`` method we set up the user interface, using a helper class to set up an adaptive user interface consisting of two leaflets: one in the window's header bar, the other in the main area of the window:
.. literalinclude:: app/src/main.py
:language: python3
:start-at: do_activate
:end-at: show_all
The leaflet in the main area holds two pages: one with a list of thumbnails; the other with a simple image viewer.
The leaflet in the main area holds two pages: one with a list of thumbnails, the other with a simple image viewer.
For the first page we use a `Gtk.ScrolledWindow`_ widget to provide a scrolling list of thumbnails. The thumbnails are held by a `Gtk.ListStore`_ object that we create, specifying the data types it holds: a ``Pixbuf`` and a string that holds the file name of the image. We populate the model by calling the ``load_thumbnails`` method which we describe later:
For the first page we use a `Gtk.ScrolledWindow`_ widget to provide a scrolling list of thumbnails. The thumbnails are held by a `Gtk.ListStore`_ object that we create, specifying the data types it holds: a ``Pixbuf`` and a string that holds the file name of the image:
.. literalinclude:: app/src/main.py
:language: python3
:start-at: def create_thumbnails_page
:end-at: load_thumbnails
We populate the model by calling the ``load_thumbnails`` method which we describe later.
The thumbnails are displayed by a `Gtk.IconView`_ widget, using the model as a data source, and mapping the fields in the model to columns in the view.
.. literalinclude:: app/src/main.py
:language: python3
:start-at: Gtk.IconView
:end-at: return page
The thumbnails are displayed by a `Gtk.IconView`_ widget, using the model as a data source, and mapping the fields in the model to columns in the view. We connect the ``item-activated`` signal to the ``show_details`` method to respond when the user clicks or touches a thumbnail.
We also connect the ``item-activated`` signal to the ``show_details`` method to respond when the user clicks or touches a thumbnail.
The second page is also a `Gtk.ScrolledWindow`_ widget, but only contains a single `Gtk.Image`_ widget that initially contains the application's own icon:
......@@ -79,9 +83,9 @@ The ``load_thumbnails`` method begins by locating the user's *Pictures* director
:start-at: def load_thumbnails
:end-at: GLib.UserDirectory.DIRECTORY_PICTURES
As described in the :ref:`gnome_settings_files` section of the :ref:`gnome_settings` guide, the `GLib.get_user_special_dir` function is used to obtain the path to the *Pictures* directory, specified using the ``DIRECTORY_PICTURES`` constant.
As described in the :ref:`gnome_settings_files` section of the :ref:`gnome_settings` guide, the ``GLib.get_user_special_dir`` function is used to obtain the path to the *Pictures* directory, specified using the ``DIRECTORY_PICTURES`` constant.
We iterate over the files in the directory, loading each of them at the size required for the thumbnails and adding them to the model created in the ``create_thumbnails_page`` method:
We iterate over the files in the directory, loading each of them at the size required for the thumbnails, and we add them to the model created in the ``create_thumbnails_page`` method:
.. literalinclude:: app/src/main.py
:language: python3
......@@ -90,8 +94,6 @@ We iterate over the files in the directory, loading each of them at the size req
Each thumbnail is added as a list of fields with types that correspond to the ones we specified when we created the `Gtk.ListStore`_ model.
Note that this method will only return once all the images have been loaded. If the user has a large number of images in their *Pictures* directory then the user interface will be unresponsive when the application starts. We could use a background thread or some kind of lazy loading mechanism to make image loading appear quicker.
The ``show_details`` method loads an image at its full size for display in the details page:
.. literalinclude:: app/src/main.py
......@@ -99,14 +101,16 @@ The ``show_details`` method loads an image at its full size for display in the d
:start-at: def show_details
:end-at: self.pages.show_page
We use the `Gtk.TreePath`_ passed to this method, along with a `Gtk.TreeIter` object, to obtain the file name of the image from the model. A good introduction to this class is provided by the `Tree and List Widgets`_ chapter of the `Python GTK+ 3 Tutorial`_.
We use the `Gtk.TreePath`_ passed to this method, along with a `Gtk.TreeIter`_ object, to obtain the file name of the image from the model. A good introduction to this class is provided by the `Tree and List Widgets`_ chapter of the `Python GTK+ 3 Tutorial`_.
Summary
-------
You can access files in specific directories in the user's home directory by calling the ``GLib.get_user_special_dir`` function to obtain the file paths you require. The directory you want to access is specified using a value from the ``GLib.UserDirectory`` enum.
You can access files in specific directories in the user's home directory by calling the `GLib.get_user_special_dir`_ function to obtain the file paths you require. The directory you want to access is specified using a value from the `GLib.UserDirectory`_ enum.
In this case we use ``DIRECTORY_PICTURES`` to access the user's *Pictures* directory and load images using the `GdkPixbuf.Pixbuf`_ class, using the ``new_from_file_at_scale`` method for thumbnails and the ``new_from_file`` method for full size images.
In this case we use ``DIRECTORY_PICTURES`` to access the user's *Pictures* directory and load images using the ``GdkPixbuf.Pixbuf`` class, using the ``new_from_file_at_scale`` method for thumbnails and the ``new_from_file`` method for full size images.
Note that the ``load_thumbnails`` method will only return once all the images have been loaded. If the user has a large number of images in their *Pictures* directory then the user interface will be unresponsive when the application starts. We could use a background thread or some kind of lazy loading mechanism to make image loading appear quicker.
.. include:: /links.txt
.. _`Tree and List Widgets`: https://python-gtk-3-tutorial.readthedocs.io/en/latest/treeview.html
.. _examples_Files_Pictures_summary:
Summary
=======
Applications that need to access user directories call the `GLib.get_user_special_dir`_ function to find the location of the directory, passing the appropriate `GLib.UserDirectory`_ value for the specific directory.
When distributed as a flatpak, the manifest needs to contain the permission that :ref:`corresponds to the directory <flatpak_app_permissions_guide_table>` being accessed. In this case, the ``--filesystem=xdg-pictures`` permission allows the application to access the user's *Pictures* directory.
Images are loaded using the `GdkPixbuf.Pixbuf`_ class and typically displayed using the `Gtk.Image`_ widget. In this example we also used the `Gtk.IconView`_ widget to display image thumbnails.
.. include:: /links.txt
......@@ -19,5 +19,6 @@ We will focus on the parts of the application that are related to reading the im
Source_Code
Building_the_App
Packaging_the_App
Summary
.. include:: /links.txt
......@@ -20,6 +20,8 @@ example, each application can store and retrieve user data in its own private
area. This mechanism for storing persistent data is described in the section
about :ref:`gnome_settings_user_data`.
.. _flatpak_app_permissions_guide_table:
Permissions for Common Features
-------------------------------
......
......@@ -15,6 +15,7 @@
.. _`Flatpak debugging documentation`: http://docs.flatpak.org/en/latest/debugging.html
.. _`Flatpak documentation`: http://docs.flatpak.org/en/latest/
.. _`Freedesktop quick reference`: http://docs.flatpak.org/en/latest/freedesktop-quick-reference.html
.. _`GdkPixbuf.Pixbuf`: https://lazka.github.io/pgi-docs/#GdkPixbuf-2.0/classes/Pixbuf.html
.. _`Gio.GApplication documentation`: https://developer.gnome.org/gio/stable/GApplication.html#g-application-id-is-valid
.. _`git-buildpackage`: http://honk.sigxcpu.org/projects/git-buildpackage/manual-html/gbp.html
.. _`GKeyFile`: https://developer.gnome.org/glib/stable/glib-Key-value-file-parser.html
......@@ -22,6 +23,8 @@
.. _`Glade Tutorials`: https://wiki.gnome.org/action/show/Apps/Glade/Tutorials
.. _`glib-compile-resources`: https://developer.gnome.org/gio/stable/glib-compile-resources.html
.. _`g_get_user_data_dir`: https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-get-user-data-dir
.. _`GLib.get_user_special_dir`: https://lazka.github.io/pgi-docs/#GLib-2.0/functions.html#GLib.get_user_special_dir
.. _`GLib.UserDirectory`: https://lazka.github.io/pgi-docs/#GLib-2.0/enums.html#GLib.UserDirectory
.. _`GMenu`: https://developer.gnome.org/gio/2.60/GMenu.html
.. _`GNOME API Reference`: https://developer.gnome.org/references
.. _`GNOME Builder`: https://wiki.gnome.org/Apps/Builder
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment