Commit 130f90d8 authored by David Boddie's avatar David Boddie 💬
Browse files

Expand the source code section of the pictures example

parent f0cdffeb
......@@ -27,8 +27,8 @@ Besides standard Python modules such as ``os`` and ``sys``, the ``Handy`` module
The ``widgets`` module contains a helper class that we won't cover in any detail.
Application Class
~~~~~~~~~~~~~~~~~
Setting up the User Interface
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``Application`` class provides the usual methods to set up the application
and perform tasks when it is run.
......@@ -49,13 +49,64 @@ In the ``do_activate`` method we set up the user interface, using a helper class
: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 ``do_activate`` method also calls the ``load_thumbnails`` method to load thumbnails for the images. This is described later.
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:
.. literalinclude:: app/src/main.py
:language: python3
:start-at: def create_thumbnails_page
: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.
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:
.. literalinclude:: app/src/main.py
:language: python3
:start-at: def create_details_page
:end-at: return page
As for the first page, we also return the widget that represents the page.
Loading and Displaying Images
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``load_thumbnails`` method begins by locating the user's *Pictures* directory:
.. literalinclude:: app/src/main.py
:language: python3
: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.
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:
.. literalinclude:: app/src/main.py
:language: python3
:start-at: os.listdir(pictures_dir)
:end-at: self.model.append
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
:language: python3
: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`_.
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.
In this case we use ``DIRECTORY_PICTURES`` to access the user's pictures directory and load images using the ``GdkPixbuf.Pixbuf`` class.
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.
.. include:: /links.txt
.. _`Tree and List Widgets`: https://python-gtk-3-tutorial.readthedocs.io/en/latest/treeview.html
......@@ -27,6 +27,8 @@ More complex and larger data is also included in the user data directories by ap
Applications distributed as flatpaks do not need to request permissions in order to access user data stored in a data directory that has been set aside for that purpose.
.. _gnome_settings_files:
Files
-----
......
......@@ -39,21 +39,28 @@
.. _GtkApplication: https://developer.gnome.org/gtk3/stable/GtkApplication.html
.. _`GtkApplicationWindow`: https://developer.gnome.org/gtk3/stable/GtkApplicationWindow.html
.. _GtkBox: https://developer.gnome.org/gtk3/stable/GtkBox.html
.. _`Gtk.Box`: https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/Box.html
.. _GtkBuilder: https://developer.gnome.org/gtk3/stable/GtkBuilder.html
.. _GtkButton : https://developer.gnome.org/gtk3/stable/GtkButton.html
.. _GtkGrid: https://developer.gnome.org/gtk3/stable/GtkGrid.html
.. _GtkHeaderBar : https://developer.gnome.org/gtk3/stable/GtkHeaderBar.html
.. _`Gtk.IconView`: https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/IconView.html
.. _`Gtk.Image`: https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/Image.html
.. _`GTK+ Inspector`: https://wiki.gnome.org/Projects/GTK+/Inspector
.. _GtkLabel ellipsize property : https://developer.gnome.org/gtk3/stable/GtkLabel.html#GtkLabel--ellipsize
.. _GtkLabel : https://developer.gnome.org/gtk3/stable/GtkLabel.html
.. _GtkLabel wrap-mode property : https://developer.gnome.org/gtk3/stable/GtkLabel.html#GtkLabel--wrap-mode
.. _GtkLabel wrap property : https://developer.gnome.org/gtk3/stable/GtkLabel.html#GtkLabel--wrap
.. _GtkLabel xalign property : https://developer.gnome.org/gtk3/stable/GtkLabel.html#GtkLabel--xalign
.. _`Gtk.ListStore`: https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/ListStore.html
.. _GtkMenuButton: https://developer.gnome.org/gtk3/stable/GtkMenuButton.html
.. _GtkSeparator : https://developer.gnome.org/gtk3/stable/GtkSeparator.html
.. _GtkScrolledWindow : https://developer.gnome.org/gtk3/stable/GtkScrolledWindow.html
.. _`Gtk.ScrolledWindow`: https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/ScrolledWindow.html
.. _GtkSizeGroup : https://developer.gnome.org/gtk3/stable/GtkSizeGroup.html
.. _GtkToolButton : https://developer.gnome.org/gtk3/stable/GtkToolButton.html
.. _Gtk.TreeIter : https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/TreeIter.html
.. _Gtk.TreePath : https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/TreePath.html
.. _`GTK+ toolkit`: https://www.gtk.org
.. _`GTK+ website`: https://www.gtk.org/
.. _HdyHeaderGroup : https://honk.sigxcpu.org/projects/libhandy/doc/HdyHeaderGroup.html
......
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