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
- 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:
- 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:- filters
list
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_disables
bool
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:
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.
- filters
- 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 usesPySide6.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 itemevent (
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 itemdeselected (
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.