qtbricks.filebrowser module

File browser widget for selecting (multiple) files from a directory tree.

Sometimes we need a convenient file browser widget displaying a directory as tree and allowing to both, navigate through the directory hierarchy and to select (multiple) files. All we are usually interested in is the (full) file names of the selected files.

There is currently just one public class in this module meant to be included as a widget into your own GUIs: FileBrowser. All other classes are meant for internal use only, although they are documented.

General characteristics and intended purpose

The file browser widget is intended to be used as an interface to select one or multiple individual files (not directories) and to return the filenames with their full path, to further operate on this information.

How to use the FileBrowser in own GUIs?

A rather minimal (and not very useful, though educational) example, including the FileBrowser as only widget of a main window:

import sys

from PySide6 import QtWidgets

from qtbricks import filebrowser


class MainWindow(QtWidgets.QMainWindow):

    def __init__(self):
        super().__init__()

        widget = filebrowser.FileBrowser()

        # Purely for debugging purposes:
        widget.selection_changed.connect(lambda x: print("Selection:", x))
        self.setCentralWidget(widget)

        self.show()


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    app.exec()

While the FileBrowser class emits FileBrowser.selection_changed signals whenever the selection of its items changed, you can always get the current selection from the FileBrowser.selection attribute. The FileBrowser.selection attribute contains the filenames including the full path for each selected file (item). Similarly, the FileBrowser.selection_changed signal contains the contents of FileBrowser.selection as payload.

Notes for developers

Wherever possible, the naming follows PEP 8 conventions. This naturally leads to some inconsistencies between the PySide6 elements and the own code.

All icons used are from the FontAwesome font (version 6), with a CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/) for the icons themselves. To decouple the location of the icons from the actual code, the qtbricks.utils.image_path() function gets used.

The entire widget is laid out programmatically, not using QtDesigner. Currently, all widgets are non-public instance attributes, allowing to define them all together in the class constructor and factoring further settings into separate methods.

Communication with the outside world beyond the widget primarily takes place via the Qt signal–slot mechanism.

Todo

Try to reimplement buttons and edit as a Qt toolbar with respective actions that can even be added to an external window?

Todo

Try to reimplement toolbar/buttons&edit such that the edit moves in a second line if the widget gets too narrow.

Todo

Provide (sensible) minimumSizeHint for FileBrowser widget.

Depending on the context the widget is used in, this seems not necessary… Hence, lower priority.

Module documentation

class qtbricks.filebrowser.FileBrowser(path='')

Bases: QWidget

File browser widget for selecting (multiple) files from a directory tree.

Sometimes we need a convenient file browser widget displaying a directory as tree and allowing to both, navigate through the directory hierarchy and to select (multiple) files. All we are usually interested in is the (full) file names of the selected files.

At the core of the widget is a tree view (a _FileTree object), but for the convenience of the user, a series of additional control widgets is added on top:

  • Buttons for home, back, up, and forward

  • A line edit displaying the current directory path

The back and forward buttons are only active once the user navigated within the directory tree. The line edit displaying the current directory path can be used as an input as well and will always be in sync with the tree view. If the user enters a non-existing directory, the edit will simply be reverted to the last (valid) path.

Multiple selections are allowed, but only files can be selected, not directories. You can select multiple files by pressing the “Ctrl” key while clicking. In the same way, you can deselect a given file. Pressing the “Shift” key when clicking selects a range of files.

Selecting files using the keyboard follows established conventions as well. Moving with the arrow keys moves the selection. Holding the “Ctrl” key when navigating with the arrow keys allows to select an additional file pressing the “Space” key. Holding the “Shift” key when navigating with the arrow keys selects an entire range of files. You can even use a sequence of holding “Ctrl” and “Shift” keys for arbitrarily complex selection patterns. Just make sure to always keep pressing either “Ctrl” or “Shift” when navigating, as otherwise, the selection will be cleared and only the current item selected. Deselecting an item is possible as well, holding the “Ctrl” key and using the “Space” key to toggle selection of the current item.

Double-clicking on a directory will change the root path to this directory.

Currently, the class has no public methods and only two public attributes and a signal documented below.

Parameters:

path (str) – Root path to be set for the file browser

root_path

Root path set currently for the file browser

Type:

str

selection

Names of the currently selected files

The names are the actual full paths to the file on the file system.

Thanks to using a list, the names should always appear in the order they have been selected.

Type:

list

selection_changed

Signal emitted when the selection of items changed.

The signal contains the selection as set parameter.

property model_settings

Settings for the underlying QFileSystemModel.

Often, when browsing the file system, we want to control (and restrict) what is displayed how. To this end, settings for the underlying model need to be set.

The settings are contained in a dict that supports the following fields:

filterslist

A list of strings to be used for filtering the files.

Typical use cases would be filters for file extensions, such as *.py or *.png.

The QFileSystemModel class only supports basic wildcard filtering, so you will need to use a QSortFilterProxyModel to get fully customisable filtering. Note however, that the latter is currently not implemented.

See https://stackoverflow.com/questions/72587813 for inspiration.

filter_disablesbool

Whether files filtered with the above filter are displayed.

The standard handling of the QFileSystemModel is to only disable, but not hide the filtered out entries. Set to False in case you want to hide the entries entirely.

Returns:

model_settings – Settings for the underlying QFileSystemModel

Return type:

dict

Note

The reason for this attribute to be a property is simple, yet deserves a comment for developers: You need to be able to set/alter the model settings after you have instantiated the class. Therefore, upon changing the settings, an internal method is called taking care of applying your settings to the model.

class qtbricks.filebrowser._FileTree(root_path='')

Bases: QTreeView

Tree view of the file system emitting names of selected files.

The tree view is based on PySide6.QtWidgets.QTreeView and uses PySide6.QtWidgets.QFileSystemModel as underlying model for the file system. Furthermore, multiple selections are allowed, but only files can be selected, not directories.

As a selection mode, QtWidgets.QAbstractItemView.ExtendedSelection is used, meaning that you can select multiple files by pressing the “Ctrl” key while clicking. In the same way, you can deselect a given file. Pressing the “Shift” key when clicking selects a range of files.

Double-clicking on a directory will change the root path to this directory.

The class emits two signals described below.

Parameters:

root_path (str) – Root path to be set for the file browser

Todo

Properly handle hiding of columns, using self.hideColumn(#)().

Todo

Context menu, allowing to set the columns to be displayed?

Todo

Allow using the “Return” key to enter directories?

root_path_changed

Signal emitted when the root path of the underlying model changed.

The signal contains the new root path as str parameter.

selection_changed

Signal emitted when the selection of items changed.

The signal contains the selection as list parameter.

set_root_path(path='')

Set the root path of the directory tree view.

Parameters:

path (str) – Path to be set as root path.

selectionCommand(index=<class 'PySide6.QtCore.QModelIndex'>, event=<class 'PySide6.QtCore.QEvent'>)

Handle selection of the underlying tree view.

In case a directory has been selected, it will automatically be deselected, thus making directories not selectable. The idea behind this behaviour is to return only files, not directories, for settings where you want to operate on one or multiple files, but not on entire directories.

For all items that are not directories, the super method is called and the parameters passed to this method.

Parameters:
  • index (QtCore.QModelIndex) – Index of the selected item

  • event (QtCore.Event) – Event sent during selection.

selectionChanged(selected, deselected)

Handle changes of selection of the underlying tree view.

A selection_changed signal is emitted, conveying the list of filenames (with their full path) corresponding to the currently selected items.

Afterwards, the super method is called and the parameters passed to this method.

Parameters:
  • selected (QtCore.QItemSelection) – Selected item

  • deselected (QtCore.QItemSelection) – Deselected item

apply_settings(model_settings)
class qtbricks.filebrowser._FileSystemModel

Bases: QFileSystemModel

Model of the file system used in the tree view.

Basically, the class is identical to its base class, currently just adding the relevant code for displaying tooltips.

data(index, role)

Text or else used to display the selected item in the given context.

Parameters:
  • index (QtCore.QModelIndex) – Index of the selected item

  • role (int) – The Qt role deciding about the context

Returns:

data – Data used to display the item

Return type:

Any