235 lines
7.3 KiB
Python
235 lines
7.3 KiB
Python
"""
|
|
Système de signaux Qt pour communication Orchestrator → GUI
|
|
Permet une communication thread-safe entre les composants
|
|
"""
|
|
|
|
from PyQt5.QtCore import QObject, pyqtSignal
|
|
from typing import Callable, Dict, Any
|
|
|
|
|
|
class GUISignals(QObject):
|
|
"""
|
|
Signaux Qt pour communication entre l'Orchestrator et la GUI.
|
|
|
|
Ces signaux permettent une communication thread-safe et asynchrone
|
|
entre le backend (Orchestrator) et l'interface utilisateur.
|
|
|
|
Signals:
|
|
log_message: Émet un message de log (emoji: str, message: str, level: str)
|
|
update_stats: Met à jour les statistiques (stats: dict)
|
|
show_dialog: Affiche un dialogue interactif (title: str, message: str, on_accept: callable, on_reject: callable)
|
|
mode_changed: Notifie un changement de mode (mode: str)
|
|
status_changed: Notifie un changement de statut (is_running: bool)
|
|
"""
|
|
|
|
# Signal pour ajouter un message de log
|
|
# Paramètres: (emoji: str, message: str, level: str)
|
|
log_message = pyqtSignal(str, str, str)
|
|
|
|
# Signal pour mettre à jour les statistiques
|
|
# Paramètre: (stats: dict) contenant actions_count, patterns_count, etc.
|
|
update_stats = pyqtSignal(dict)
|
|
|
|
# Signal pour afficher un dialogue interactif
|
|
# Paramètres: (title: str, message: str, on_accept: object, on_reject: object)
|
|
show_dialog = pyqtSignal(str, str, object, object)
|
|
|
|
# Signal pour notifier un changement de mode
|
|
# Paramètre: (mode: str) - 'shadow', 'assist', 'copilot', 'auto'
|
|
mode_changed = pyqtSignal(str)
|
|
|
|
# Signal pour notifier un changement de statut
|
|
# Paramètre: (is_running: bool)
|
|
status_changed = pyqtSignal(bool)
|
|
|
|
def __init__(self):
|
|
"""Initialise le système de signaux."""
|
|
super().__init__()
|
|
|
|
def emit_log(self, emoji: str, message: str, level: str = "info"):
|
|
"""
|
|
Émet un signal de log.
|
|
|
|
Args:
|
|
emoji: Emoji à afficher
|
|
message: Message de log
|
|
level: Niveau du log ('info', 'success', 'warning', 'error')
|
|
|
|
Examples:
|
|
>>> signals = GUISignals()
|
|
>>> signals.emit_log("👀", "J'observe vos actions", "info")
|
|
"""
|
|
self.log_message.emit(emoji, message, level)
|
|
|
|
def emit_stats_update(self, stats: Dict[str, Any]):
|
|
"""
|
|
Émet un signal de mise à jour des statistiques.
|
|
|
|
Args:
|
|
stats: Dictionnaire contenant les statistiques
|
|
{
|
|
'actions_count': int,
|
|
'patterns_count': int,
|
|
'workflows_count': int,
|
|
'finetuning_status': str,
|
|
'finetuning_progress': int
|
|
}
|
|
|
|
Examples:
|
|
>>> signals = GUISignals()
|
|
>>> signals.emit_stats_update({
|
|
... 'actions_count': 12,
|
|
... 'patterns_count': 2,
|
|
... 'workflows_count': 1
|
|
... })
|
|
"""
|
|
self.update_stats.emit(stats)
|
|
|
|
def emit_dialog(self, title: str, message: str,
|
|
on_accept: Callable, on_reject: Callable):
|
|
"""
|
|
Émet un signal pour afficher un dialogue interactif.
|
|
|
|
Args:
|
|
title: Titre du dialogue
|
|
message: Message du dialogue
|
|
on_accept: Callback appelé si l'utilisateur accepte
|
|
on_reject: Callback appelé si l'utilisateur refuse
|
|
|
|
Examples:
|
|
>>> signals = GUISignals()
|
|
>>> def accept():
|
|
... print("Accepté")
|
|
>>> def reject():
|
|
... print("Refusé")
|
|
>>> signals.emit_dialog(
|
|
... "Confirmation",
|
|
... "Voulez-vous continuer ?",
|
|
... accept,
|
|
... reject
|
|
... )
|
|
"""
|
|
self.show_dialog.emit(title, message, on_accept, on_reject)
|
|
|
|
def emit_mode_change(self, mode: str):
|
|
"""
|
|
Émet un signal de changement de mode.
|
|
|
|
Args:
|
|
mode: Nouveau mode ('shadow', 'assist', 'copilot', 'auto')
|
|
|
|
Examples:
|
|
>>> signals = GUISignals()
|
|
>>> signals.emit_mode_change("assist")
|
|
"""
|
|
self.mode_changed.emit(mode)
|
|
|
|
def emit_status_change(self, is_running: bool):
|
|
"""
|
|
Émet un signal de changement de statut.
|
|
|
|
Args:
|
|
is_running: True si le système est en cours d'exécution
|
|
|
|
Examples:
|
|
>>> signals = GUISignals()
|
|
>>> signals.emit_status_change(True)
|
|
"""
|
|
self.status_changed.emit(is_running)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
"""Tests du système de signaux"""
|
|
from PyQt5.QtWidgets import QApplication
|
|
import sys
|
|
|
|
app = QApplication(sys.argv)
|
|
|
|
print("Test du système de signaux Qt")
|
|
print("=" * 50)
|
|
|
|
# Créer une instance de signaux
|
|
signals = GUISignals()
|
|
|
|
# Compteurs pour vérifier les émissions
|
|
log_count = 0
|
|
stats_count = 0
|
|
dialog_count = 0
|
|
mode_count = 0
|
|
status_count = 0
|
|
|
|
# Connecter des slots de test
|
|
def on_log(emoji, message, level):
|
|
global log_count
|
|
log_count += 1
|
|
print(f"\n✓ Log reçu: {emoji} {message} [{level}]")
|
|
|
|
def on_stats(stats):
|
|
global stats_count
|
|
stats_count += 1
|
|
print(f"\n✓ Stats reçues: {stats}")
|
|
|
|
def on_dialog(title, message, on_accept, on_reject):
|
|
global dialog_count
|
|
dialog_count += 1
|
|
print(f"\n✓ Dialogue reçu: {title} - {message}")
|
|
|
|
def on_mode(mode):
|
|
global mode_count
|
|
mode_count += 1
|
|
print(f"\n✓ Mode changé: {mode}")
|
|
|
|
def on_status(is_running):
|
|
global status_count
|
|
status_count += 1
|
|
print(f"\n✓ Statut changé: {'En cours' if is_running else 'Arrêté'}")
|
|
|
|
# Connecter les signaux
|
|
signals.log_message.connect(on_log)
|
|
signals.update_stats.connect(on_stats)
|
|
signals.show_dialog.connect(on_dialog)
|
|
signals.mode_changed.connect(on_mode)
|
|
signals.status_changed.connect(on_status)
|
|
|
|
print("\n1. Test émission de log:")
|
|
signals.emit_log("👀", "Test message", "info")
|
|
|
|
print("\n2. Test émission de stats:")
|
|
signals.emit_stats_update({
|
|
'actions_count': 12,
|
|
'patterns_count': 2,
|
|
'workflows_count': 1
|
|
})
|
|
|
|
print("\n3. Test émission de dialogue:")
|
|
signals.emit_dialog(
|
|
"Test",
|
|
"Message de test",
|
|
lambda: print("Accepté"),
|
|
lambda: print("Refusé")
|
|
)
|
|
|
|
print("\n4. Test émission de changement de mode:")
|
|
signals.emit_mode_change("assist")
|
|
|
|
print("\n5. Test émission de changement de statut:")
|
|
signals.emit_status_change(True)
|
|
|
|
# Traiter les événements Qt
|
|
app.processEvents()
|
|
|
|
# Vérifier les compteurs
|
|
print("\n" + "=" * 50)
|
|
print("Résultats:")
|
|
print(f" Logs émis: {log_count}")
|
|
print(f" Stats émises: {stats_count}")
|
|
print(f" Dialogues émis: {dialog_count}")
|
|
print(f" Modes émis: {mode_count}")
|
|
print(f" Statuts émis: {status_count}")
|
|
|
|
if all([log_count == 1, stats_count == 1, dialog_count == 1,
|
|
mode_count == 1, status_count == 1]):
|
|
print("\n✅ Tous les tests passent!")
|
|
else:
|
|
print("\n❌ Certains tests ont échoué")
|