"""Main Window - Modern GUI connected to core""" from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * from .orchestrator import RPAOrchestrator import logging logger = logging.getLogger(__name__) class MainWindow(QMainWindow): """Modern GUI with orchestrator integration""" def __init__(self): super().__init__() self.setWindowTitle("RPA Vision V3") self.setGeometry(100, 100, 800, 600) # Create orchestrator self.orchestrator = RPAOrchestrator() self._connect_orchestrator() self._init_ui() logger.info("MainWindow initialized") def _connect_orchestrator(self): """Connect orchestrator signals""" self.orchestrator.log_message.connect(self.add_log) self.orchestrator.status_updated.connect(self.update_status) self.orchestrator.training_progress.connect(self.update_training_progress) def _init_ui(self): """Initialize UI""" central = QWidget() self.setCentralWidget(central) layout = QVBoxLayout(central) layout.addWidget(self._create_header()) self.tabs = QTabWidget() self.tabs.addTab(self._create_live_tab(), "🔴 Live") self.tabs.addTab(self._create_workflows_tab(), "📊 Workflows") self.tabs.addTab(self._create_training_tab(), "🎓 Training") layout.addWidget(self.tabs) layout.addWidget(self._create_controls()) def _create_header(self): widget = QWidget() layout = QHBoxLayout(widget) self.status_label = QLabel("État: 🟢 OBSERVATION") self.status_label.setStyleSheet("font-size: 14px; font-weight: bold;") layout.addWidget(self.status_label) layout.addStretch() self.confidence_label = QLabel("Confiance: --") layout.addWidget(self.confidence_label) self.workflows_label = QLabel("Workflows: 0") layout.addWidget(self.workflows_label) return widget def _create_live_tab(self): widget = QWidget() layout = QVBoxLayout(widget) self.logs_text = QTextEdit() self.logs_text.setReadOnly(True) self.logs_text.setStyleSheet("background: #1e1e1e; color: #d4d4d4; font-family: monospace;") layout.addWidget(self.logs_text) return widget def _create_workflows_tab(self): widget = QWidget() layout = QVBoxLayout(widget) self.workflows_table = QTableWidget(0, 4) self.workflows_table.setHorizontalHeaderLabels(["ID", "État", "Succès", "Exécutions"]) self.workflows_table.horizontalHeader().setStretchLastSection(True) layout.addWidget(self.workflows_table) refresh_btn = QPushButton("🔄 Refresh") refresh_btn.clicked.connect(self.refresh_workflows) layout.addWidget(refresh_btn) return widget def _create_training_tab(self): widget = QWidget() layout = QVBoxLayout(widget) layout.addWidget(QLabel("Sessions collectées:")) self.training_progress = QProgressBar() self.training_progress.setMaximum(100) layout.addWidget(self.training_progress) self.training_stats = QTextEdit() self.training_stats.setReadOnly(True) self.training_stats.setMaximumHeight(200) layout.addWidget(self.training_stats) btn_layout = QHBoxLayout() self.export_btn = QPushButton("📤 Export Data") self.export_btn.clicked.connect(self.export_training_data) self.train_btn = QPushButton("🎯 Train Model") self.train_btn.clicked.connect(self.train_model) btn_layout.addWidget(self.export_btn) btn_layout.addWidget(self.train_btn) layout.addLayout(btn_layout) layout.addStretch() return widget def _create_controls(self): widget = QWidget() layout = QHBoxLayout(widget) self.start_btn = QPushButton("▶ Start") self.start_btn.setStyleSheet("background: #4CAF50; color: white; padding: 10px; font-size: 14px;") self.start_btn.clicked.connect(self.on_start) self.pause_btn = QPushButton("⏸ Pause") self.pause_btn.setEnabled(False) self.pause_btn.clicked.connect(self.on_pause) self.stop_btn = QPushButton("⏹ Stop") self.stop_btn.setEnabled(False) self.stop_btn.clicked.connect(self.on_stop) layout.addWidget(self.start_btn) layout.addWidget(self.pause_btn) layout.addWidget(self.stop_btn) return widget def on_start(self): """Start button clicked""" self.orchestrator.start() self.start_btn.setEnabled(False) self.pause_btn.setEnabled(True) self.stop_btn.setEnabled(True) def on_pause(self): """Pause button clicked""" if self.pause_btn.text() == "⏸ Pause": self.orchestrator.pause() self.pause_btn.setText("▶ Resume") else: self.orchestrator.resume() self.pause_btn.setText("⏸ Pause") def on_stop(self): """Stop button clicked""" self.orchestrator.stop() self.start_btn.setEnabled(True) self.pause_btn.setEnabled(False) self.stop_btn.setEnabled(False) self.pause_btn.setText("⏸ Pause") def add_log(self, message: str): """Add log message""" from datetime import datetime timestamp = datetime.now().strftime("%H:%M:%S") self.logs_text.append(f"[{timestamp}] {message}") def update_status(self, state: str, confidence: float, workflows: int): """Update header status""" icons = { "OBSERVATION": "🟢", "COACHING": "🟡", "AUTO_CANDIDATE": "🟠", "AUTO_CONFIRMED": "🔴" } icon = icons.get(state, "⚪") self.status_label.setText(f"État: {icon} {state}") self.confidence_label.setText(f"Confiance: {confidence:.0%}") self.workflows_label.setText(f"Workflows: {workflows}") def update_training_progress(self, current: int, total: int): """Update training progress bar""" self.training_progress.setValue(current) self.training_progress.setMaximum(total) def refresh_workflows(self): """Refresh workflows table""" workflows = self.orchestrator.get_workflows() self.workflows_table.setRowCount(len(workflows)) for i, wf in enumerate(workflows): self.workflows_table.setItem(i, 0, QTableWidgetItem(wf['id'])) self.workflows_table.setItem(i, 1, QTableWidgetItem(wf['state'])) self.workflows_table.setItem(i, 2, QTableWidgetItem(f"{wf['success_rate']:.0%}")) self.workflows_table.setItem(i, 3, QTableWidgetItem(str(wf['executions']))) self.add_log(f"✓ Refreshed {len(workflows)} workflows") def export_training_data(self): """Export training data""" if self.orchestrator.export_training_data(): QMessageBox.information(self, "Success", "Training data exported successfully!") def train_model(self): """Train model""" reply = QMessageBox.question( self, "Train Model", "This will train a new model on collected data. Continue?", QMessageBox.Yes | QMessageBox.No ) if reply == QMessageBox.Yes: if self.orchestrator.train_model(): QMessageBox.information(self, "Success", "Model trained successfully!")