.. |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.
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
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.