2025-05-01 19:16:37 +02:00

9.6 KiB

Developer Guide: GUI Internals

This document provides technical details about the implementation of the Graphical User Interface (GUI) for developers.

Framework

The GUI is built using PySide6, which provides Python bindings for the Qt framework.

Main Window (gui/main_window.py)

The MainWindow class is the central component of the GUI application. It is responsible for:

  • Defining the main application window structure and layout using PySide6 widgets.
  • Arranging the Preset Editor panel (left) and the Unified Hierarchical View (right).
  • Setting up the menu bar, including the "View" menu for toggling the Log Console.
  • Connecting user interactions (button clicks, drag-and-drop events, edits in the Unified View) to corresponding methods (slots) within the MainWindow or other handler classes.
  • Managing the display of application logs in the UI console using a custom QtLogHandler.
  • Interacting with background handlers (ProcessingHandler, PredictionHandler) via Qt signals and slots to ensure thread-safe updates to the UI during long-running operations.
  • Accumulating prediction results from the PredictionHandler for multiple input sources before updating the UnifiedViewModel.
  • Receiving the initial SourceRule hierarchy from the PredictionHandler and populating the UnifiedViewModel.
  • Sending the final, potentially user-modified, SourceRule list to main.py to initiate processing via the ProcessingEngine.

Threading and Background Tasks

To keep the UI responsive during intensive operations like asset processing and rule prediction, the GUI utilizes background threads managed by QThread.

  • ProcessingHandler (gui/processing_handler.py): This class is designed to run in a separate QThread. It manages the execution of the main asset processing pipeline using the ProcessingEngine for multiple assets concurrently using concurrent.futures.ProcessPoolExecutor. It submits individual asset processing tasks to the pool, passing the relevant SourceRule object and Configuration instance to the ProcessingEngine. It monitors task completion and communicates progress, status updates, and results back to the MainWindow on the main UI thread using Qt signals. It also handles the execution of optional Blender scripts via subprocess calls after processing.
  • PredictionHandler (gui/prediction_handler.py): This class also runs in a separate QThread. It is responsible for generating the initial SourceRule hierarchy with predicted values based on the input files and the selected preset. It uses logic (including accessing preset rules and config.py's allowed types) to analyze files and predict initial values for overridable fields in the SourceRule, AssetRule, and FileRule objects (e.g., asset type, item type, target asset name). It constructs the complete SourceRule hierarchy based on these predictions and emits a signal (rule_hierarchy_ready) with the generated List[SourceRule] to the MainWindow to populate the Unified Hierarchical View.

Communication (Signals and Slots)

Communication between the main UI thread (MainWindow) and the background threads (ProcessingHandler, PredictionHandler) relies heavily on Qt's signals and slots mechanism. This is a thread-safe way for objects in different threads to communicate.

  • Background handlers emit signals to indicate events (e.g., progress updated, file status changed, task finished).
  • The MainWindow connects slots (methods) to these signals. When a signal is emitted, the connected slot is invoked on the thread that owns the receiving object (the main UI thread for MainWindow), ensuring UI updates happen safely.

Preset Editor

The GUI includes an integrated preset editor panel. This allows users to interactively create, load, modify, and save preset .json files directly within the application. The editor typically uses standard UI widgets to display and edit the key fields of the preset structure.

Unified Hierarchical View (gui/unified_view_model.py, gui/delegates.py)

The core of the GUI's rule editing interface is the Unified Hierarchical View, implemented using a QTreeView with a custom model and delegates.

  • Unified View Model (gui/unified_view_model.py): This class implements a QAbstractItemModel to expose the structure of a list of SourceRule objects (Source -> Asset -> File) to the QTreeView. It holds the SourceRule data that is the single source of truth for the GUI's processing rules. It provides data and flags for display in multiple columns and supports inline editing of specific rule attributes (e.g., asset type, item type override, target asset name override) by interacting with delegates.
    • Direct Model Restructuring: The setData method now includes logic to directly restructure the underlying SourceRule hierarchy when the target_asset_name_override field of a FileRule is edited. This involves moving the FileRule to a different AssetRule (creating a new one if necessary) and removing the old AssetRule if it becomes empty. This replaces the previous mechanism of re-running prediction after an edit.
    • Row Coloring: Row background colors are dynamically determined based on the asset_type (for AssetRules) and item_type or item_type_override (for FileRules), using the color metadata defined in the ASSET_TYPE_DEFINITIONS and FILE_TYPE_DEFINITIONS dictionaries sourced from the configuration loaded by configuration.py (which includes data from config/app_settings.json). SourceRule rows have a fixed color.
    • Delegates (gui/delegates.py): This module contains custom QStyledItemDelegate implementations used by the QTreeView to provide inline editors for specific data types or rule attributes.
    • ComboBoxDelegate: Used for selecting from predefined lists (e.g., allowed asset types, allowed file types sourced from the configuration loaded by configuration.py).
    • LineEditDelegate: Used for free-form text editing (e.g., target asset name override).
    • SupplierSearchDelegate: A new delegate used for the "Supplier" column. It provides a QLineEdit with auto-completion suggestions loaded from config/suppliers.json. It also handles adding new, unique supplier names entered by the user to the list and saving the updated list back to the JSON file.

The PredictionHandler generates the initial SourceRule hierarchy, which is then set on the UnifiedViewModel. The QTreeView displays this model, allowing users to navigate the hierarchy and make inline edits to the rule attributes. Edits made in the view directly modify the attributes of the underlying rule objects in the SourceRule hierarchy held by the model, with the UnifiedViewModel handling the necessary model restructuring and signal emission for view updates.

Data Flow Diagram (GUI Rule Management):

graph LR
    A[User Input (Drag/Drop, Preset Select)] --> B(MainWindow);
    B -- Calls --> C(PredictionHandler);
    C -- Generates SourceRule Hierarchy with Predictions --> D(UnifiedViewModel);
    B -- Sets Model --> E(QTreeView - Unified View);
    E -- Displays Data from --> D;
    E -- Uses Delegates from --> F(Delegates);
    F -- Interact with --> D;
    User -- Edits Rules via --> E;
    E -- Updates Data in --> D;
    B -- Triggers Processing with Final SourceRule List --> G(main.py / ProcessingHandler);

Application Styling

The application style is explicitly set to 'Fusion' in gui/main_window.py to provide a more consistent look and feel across different operating systems. A custom QPalette is also applied to the application to adjust default colors within the 'Fusion' style.

Logging

A custom QtLogHandler is used to redirect log messages from the standard Python logging module to a text area or console widget within the GUI, allowing users to see detailed application output and errors.

Cancellation

The GUI provides a "Cancel" button to stop ongoing processing. The ProcessingHandler implements logic to handle cancellation requests. This typically involves setting an internal flag and attempting to shut down the ProcessPoolExecutor. However, it's important to note that this does not immediately terminate worker processes that are already executing; it primarily prevents new tasks from starting and stops processing results from completed futures once the cancellation flag is checked.

GUI Configuration Editor (gui/config_editor_dialog.py)

A dedicated dialog, implemented in gui/config_editor_dialog.py, provides a graphical interface for editing the core application settings stored in config/app_settings.json.

  • Functionality: This dialog loads the current content of config/app_settings.json, presents it in an editable format (likely using standard Qt widgets), and allows the user to save modifications back to the file.
  • Integration: The MainWindow is responsible for creating and displaying an instance of this dialog when the user selects the "Edit" -> "Preferences..." menu option.
  • Persistence: Changes saved via this editor are written directly to the config/app_settings.json file, ensuring they persist across application sessions. However, the Configuration class loads settings at application startup, so a restart is required for changes made in the editor to take effect in the application's processing logic.

These key components work together to provide the tool's functionality, separating concerns and utilizing concurrency for performance and responsiveness. The Unified Hierarchical View centralizes rule management in the GUI, and the SourceRule object serves as a clear data contract passed to the processing engine.