Widgets - Capsize-Games/airunner GitHub Wiki
Widgets in AI Runner are built using PySide6 and extend from the BaseWidget
class, which provides common functionality such as state management, signal handling, and UI initialization. This document provides an overview of how widgets work, including the BaseWidget
class, MediatorMixin
, and specific widget implementations.
The BaseWidget
class is the foundation for all widgets in AI Runner. It provides:
- State Persistence: Methods for saving and restoring widget state (save_state
and restore_state
).
- Signal Handling: Uses MediatorMixin
to register and emit signals.
- UI Initialization: Automatically sets up the widget’s UI and icons.
- Worker Initialization: Supports background tasks through worker class mapping.
-
splitters
: List of splitter names in the UI for saving and restoring positions. -
current_tool
: Retrieves the currently active tool in the canvas. -
is_dark
: Returns whether the application is in dark mode.
-
initialize()
: Callsinitialize_workers
andinitialize_form
to set up the widget. -
initialize_workers()
: Instantiates background worker tasks. -
save_state()
: Saves the state of UI elements (such as splitters). -
restore_state()
: Restores the widget’s previous state. -
handle_close()
: Handles application quit events. -
set_icons()
: Updates icons based on the theme.
MediatorMixin
enables widgets to communicate using a centralized SignalMediator
. This is useful for decoupling components and handling global events.
-
Widgets define a dictionary
signal_handlers
that maps signal codes to functions. -
MediatorMixin
automatically registers these handlers with theSignalMediator
. -
Signals can be emitted using
emit_signal()
and received using the registered handlers.
When creating a new widget, it must extend BaseWidget
and define signal_handlers
before calling super().init(*args, **kwargs)
. This ensures that signals are properly registered before the widget is initialized.
from airunner.widgets.base_widget import BaseWidget
from airunner.enums import SignalCode
class ExampleWidget(BaseWidget):
def __init__(self, *args, **kwargs):
self.signal_handlers = {
SignalCode.EXAMPLE_SIGNAL: self.handle_example_signal
}
super().__init__(*args, **kwargs)
def handle_example_signal(self, message):
print("Handling example signal:", message)
AI Runner uses UI templates created and modified with the PySide6 Designer. To launch the designer:
pyside6-designer
Templates (.ui
files) are stored in the templates
directories within widgets
and windows
.
Example:
airunner/src/airunner/gui
├── widgets
│ ├── llm
│ │ ├── templates
│ │ │ ├── chat_prompt.ui # UI Template
│ │ │ └── chat_prompt_ui.py # Compiled UI
│ │ └── chat_prompt_widget.py # Widget Implementation
Widgets use PySide6’s signal-slot mechanism for event handling.
Example:
@Slot(str)
def handle_token_signal(self, val: str):
if val != "[END]":
text = self.ui.conversation.toPlainText()
text += val
self.ui.conversation.setPlainText(text)
else:
self.stop_progress_bar()
self.generating = False
self.enable_send_button()