diff --git a/ui/hud_overlay_clean.py b/ui/hud_overlay_clean.py index 404893f..b6b41ae 100644 --- a/ui/hud_overlay_clean.py +++ b/ui/hud_overlay_clean.py @@ -295,7 +295,6 @@ class HUDOverlay(QWidget): position_changed = pyqtSignal(QPoint) stats_updated = pyqtSignal(dict) - refresh_needed = pyqtSignal() # Signal to trigger refresh on main thread def __init__(self, parent=None, config_path: Optional[str] = None): super().__init__(parent) @@ -324,8 +323,11 @@ class HUDOverlay(QWidget): self._timer = QTimer(self) self._timer.timeout.connect(self._update_session_time) - # Connect refresh signal to ensure GUI updates happen on main thread - self.refresh_needed.connect(self._refresh_display, Qt.ConnectionType.QueuedConnection) + # Batch refresh timer - prevents too frequent GUI updates + self._refresh_pending = False + self._refresh_timer = QTimer(self) + self._refresh_timer.timeout.connect(self._do_refresh) + self._refresh_timer.start(100) # Refresh at most 10 times per second def _load_hud_config(self) -> HUDConfig: """Load HUD configuration.""" @@ -784,6 +786,16 @@ class HUDOverlay(QWidget): # Widget was deleted pass + def _request_refresh(self): + """Request a refresh - will be batched and executed on main thread.""" + self._refresh_pending = True + + def _do_refresh(self): + """Actually perform the refresh if pending.""" + if self._refresh_pending: + self._refresh_pending = False + self._refresh_display() + def _refresh_display(self): """Refresh all display labels.""" try: @@ -869,7 +881,7 @@ class HUDOverlay(QWidget): self._stats.recalculate() # Emit signal to refresh on main thread instead of calling directly - self.refresh_needed.emit() + self._request_refresh() logger.debug(f"[HUD] update_loot complete: shrapnel={self._stats.shrapnel_total}, other={self._stats.loot_other}") def update_shrapnel(self, amount: Decimal): @@ -883,7 +895,7 @@ class HUDOverlay(QWidget): self._stats.weapon_cost_total += cost_ped self._stats.cost_total += cost_ped self._stats.recalculate() - self.refresh_needed.emit() + self._request_refresh() def update_armor_cost(self, cost_ped: Decimal): """Update armor cost.""" @@ -892,7 +904,7 @@ class HUDOverlay(QWidget): self._stats.armor_cost_total += cost_ped self._stats.cost_total += cost_ped self._stats.recalculate() - self.refresh_needed.emit() + self._request_refresh() def update_healing_cost(self, cost_ped: Decimal): """Update healing cost.""" @@ -901,14 +913,14 @@ class HUDOverlay(QWidget): self._stats.healing_cost_total += cost_ped self._stats.cost_total += cost_ped self._stats.recalculate() - self.refresh_needed.emit() + self._request_refresh() def update_kills(self, count: int = 1): """Update kill count.""" logger.debug(f"[HUD] update_kills called: count={count}, session_active={self.session_active}") if self.session_active: self._stats.kills += count - self.refresh_needed.emit() + self._request_refresh() def update_skill(self, skill_name: str, amount: Decimal): """Update skill gain tracking.""" @@ -920,13 +932,13 @@ class HUDOverlay(QWidget): self._stats.skill_gains[skill_name] += amount # Update total self._stats.total_skill_gained += amount - self.refresh_needed.emit() + self._request_refresh() def update_globals(self): """Update global count.""" if self.session_active: self._stats.globals_count += 1 - self.refresh_needed.emit() + self._request_refresh() def update_damage(self, dealt: Decimal = Decimal('0'), taken: Decimal = Decimal('0')): """Update damage stats.""" @@ -935,7 +947,7 @@ class HUDOverlay(QWidget): self._stats.damage_dealt += dealt if taken > 0: self._stats.damage_taken += taken - self.refresh_needed.emit() + self._request_refresh() # === Event Handlers for LogWatcher === @@ -943,20 +955,20 @@ class HUDOverlay(QWidget): """Handle global event from LogWatcher.""" if self.session_active: self._stats.globals_count += 1 - self.refresh_needed.emit() + self._request_refresh() def on_hof(self, value_ped=Decimal('0.0')): """Handle Hall of Fame event from LogWatcher.""" if self.session_active: self._stats.hofs_count += 1 - self.refresh_needed.emit() + self._request_refresh() def on_personal_global(self, value_ped=Decimal('0.0')): """Handle personal global event from LogWatcher.""" # Only count personal globals, not all globals if self.session_active: self._stats.globals_count += 1 - self.refresh_needed.emit() + self._request_refresh() def on_damage_dealt(self, damage): """Handle damage dealt event from LogWatcher."""