diff options
Diffstat (limited to 'sources/pyside6/doc/tutorials/extendedexplorer/extendedexplorer.md')
-rw-r--r-- | sources/pyside6/doc/tutorials/extendedexplorer/extendedexplorer.md | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/sources/pyside6/doc/tutorials/extendedexplorer/extendedexplorer.md b/sources/pyside6/doc/tutorials/extendedexplorer/extendedexplorer.md new file mode 100644 index 000000000..0ac7bec18 --- /dev/null +++ b/sources/pyside6/doc/tutorials/extendedexplorer/extendedexplorer.md @@ -0,0 +1,210 @@ +# Extending the file system explorer example + +This tutorial shows how to extend the +[Filesystem Explorer Example](filesystemexplorer_example) +by adding a simple scheme manager. This feature will allow you to switch color +schemes during the application's runtime. The color schemes will be declared in +JSON format and made available through a custom Python-QML plugin. + +![Extended Explorer GIF](resources/extendedexplorer.gif) + +## Defining the color schemes + +To define your color scheme, you can use the same color names as the original +example, so you don't have to rename every occurrence. The original colors are +defined in the `Colors.qml` file as follows: + +```{literalinclude} resources/Colors.qml +--- +language: QML +caption: true +linenos: true +lines: 7-22 +--- +``` + +The `schemes.json` file holds the color schemes. To start implementing this, you +can use the [Catppuccin](https://github.com/catppuccin/catppuccin) scheme. + +```{literalinclude} schemes.json +---json +caption: true +linenos: true +start-at: "Catppuccin" +end-at: "}," +--- +``` + +In addition to the "Catppuccin" color scheme, four other color schemes got +implemented: Nordic, One Dark, Gruvbox, and Solarized. However, feel free to get +creative and experiment with **your** schemes. + +To define a new color scheme, copy the structure from above and provide your +color values + +## Implement the scheme manager + +After defining the color schemes, you can implement the actual scheme manager. +The manager will read the `schemes.json` file and provide QML bindings to switch +between schemes during runtime. + +To implement the scheme manager, create a Python-QML plugin that exposes the +`SchemeManager` object to QML. This object will have methods to load the color +schemes from the `schemes.json` file and switch between them. + +Create a new Python file called `schememanager.py` in your project directory. In +this file, define the **SchemeManager** class: + +```{literalinclude} scheme_manager.py +--- +language: python +caption: true +linenos: true +start-at: "QML_IMPORT_NAME" +end-at: "class SchemeManager" +--- +``` + +To integrate smoothly into the already existing code, attach the SchemeManager +to the same QML module that's already present with +`QML_IMPORT_NAME = "FileSystemModule"`. Additionally, use the`@QmlNamedElement` +decorator to smoothly transition to using the custom plugin instead of the +`Colors.qml` file. With these changes, we can avoid editing all previous +assignments like: + +```QML +import FileSystemModule +... +Rectangle { + color: Colors.background +} +``` + +The constructor reads the `schemes.json` file once upon application start and +then calls the `setTheme` member function. + +```{literalinclude} scheme_manager.py +--- +language: python +caption: true +linenos: true +lines: 18-24 +--- +``` + +By adding the `SchemeManager` as a callable QML element named **Colors** to the +FileSystemModule, the class is now accessible in the code without the need to +import it each time or edit previous assignments. This, in turn, will streamline +the workflow. + +After defining the schemes in the JSON format and making the `SchemeManager` +class a callable element from QML under the name **Colors**, there are two +remaining steps to fully integrate the new scheme manager in the example. + +The **first step** is to create a function in the `SchemeManager` class that +loads a color scheme from the JSON file. The **second step** is to make the +individual colors available in QML with the *same name* as used before with the +syntax `Colors.<previousName>` as assignable properties. + + +```{literalinclude} scheme_manager.py +--- +language: python +caption: true +linenos: true +lines: 26-31 +--- +``` + +The `setScheme` method is responsible for switching between color schemes. To +make this method accessible in QML, use the `@Slot(str)` decorator and specify +that it takes a string as its input parameter. In this method, we populate a +dictionary with the color values from the JSON file. + +> Note: For simplicity reasons no other error checking is performed. +> You would probably want to validate the keys contained in the json. + +```{literalinclude} scheme_manager.py +--- +language: python +caption: true +linenos: true +start-at: "@Property(QColor" +end-at: "return" +--- +``` + +To make the color property assignable in QML, use the `@Property` decorator. +We simply return the corresponding color value from the dictionary for each +property. This process is repeated for all other colors that are used in the +application. +At this point the application should start with the colors provided by the +active scheme in the constructor. + +## Add the scheme switching to QML + +To visualize the current scheme and enable interactive scheme switching, start +by adding a new entry to the `Sidebar.qml` file. + +```{literalinclude} FileSystemModule/qml/Sidebar.qml +--- +language: QML +caption: true +linenos: true +lines: 99-105 +--- +``` + +To update the main content area of the application to display the `ColorScheme`, +the logic that checks the active index from the Sidebar buttons needs to be +modified. The necessary changes will be made to the Main.qml file: + +```{literalinclude} FileSystemModule/Main.qml +--- +language: QML +caption: true +linenos: true +lines: 170-187 +--- +``` + +In addition, change the behavior of the application so that there are two +`StackLayouts`: one for the resizable navigation and one for the main content +area where we display our color scheme switching functionality. These changes +will also be made to the Main.qml file. + +```{literalinclude} FileSystemModule/Main.qml +--- +language: QML +caption: true +linenos: true +lines: 147-150 +--- +``` + +To complete our implementation, the `ColorScheme.qml` file needs to be created. +The implementation is straightforward and follows the same principles as in the +original example. If anything is unclear, please refer to the documentation +provided there. To display all colors and scheme names, use a `Repeater`. The +model for the Repeater is provided by our `scheme_manager.py`file as a +`QStringList`. + +```{literalinclude} FileSystemModule/qml/ColorScheme.qml +--- +language: QML +caption: true +linenos: true +lines: 97-111 +--- +``` + +When examining the code in more detail, you will notice that there are different +ways to retrieve the models. The `getKeys()` method is defined as a **Slot** and +therefore requires parentheses when called. On the other hand, the `currentColors` +model is defined as a **property** and is therefore assigned as a property in QML. +The reason for this is to receive notifications when the color scheme is switched +so that the colors displayed in the application can be updated. The keys for the +color schemes are loaded only once at application startup and do not rely on any +notifications. + +![Extended Explorer GIF](resources/colorscheme.png) |