fix: add logger import and safe widget access for HUD rebuild
- Add logging import and logger instance - Add _safe_set_text() helper to handle deleted widgets gracefully - Use safe access in _refresh_display to prevent RuntimeError on rebuild - Wrap stylesheet updates in try/except for safety
This commit is contained in:
parent
7a55e3b246
commit
64a68f3857
|
|
@ -5,12 +5,15 @@ Cleaner, customizable HUD with collapsible sections.
|
|||
|
||||
import sys
|
||||
import json
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from decimal import Decimal
|
||||
from datetime import datetime, timedelta
|
||||
from dataclasses import dataclass, asdict, field
|
||||
from typing import Optional, Dict, Any, List, Set
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Windows-specific imports for click-through support
|
||||
if sys.platform == 'win32':
|
||||
import ctypes
|
||||
|
|
@ -659,72 +662,72 @@ class HUDOverlay(QWidget):
|
|||
if hasattr(self, 'time_label'):
|
||||
self.time_label.setText(f"{hours:02d}:{minutes:02d}:{seconds:02d}")
|
||||
|
||||
def _safe_set_text(self, widget_name: str, text: str):
|
||||
"""Safely set text on a widget if it exists and is valid."""
|
||||
try:
|
||||
widget = getattr(self, widget_name, None)
|
||||
if widget is not None:
|
||||
widget.setText(text)
|
||||
except RuntimeError:
|
||||
# Widget was deleted
|
||||
pass
|
||||
|
||||
def _refresh_display(self):
|
||||
"""Refresh all display labels."""
|
||||
# Profit/Loss
|
||||
if hasattr(self, 'profit_label'):
|
||||
profit = self._stats.profit_loss
|
||||
color = "#7FFF7F" if profit >= 0 else "#FF7F7F"
|
||||
self.profit_label.setText(f"{profit:+.2f} PED")
|
||||
self.profit_label.setStyleSheet(f"font-size: 18px; font-weight: bold; color: {color};")
|
||||
profit = self._stats.profit_loss
|
||||
color = "#7FFF7F" if profit >= 0 else "#FF7F7F"
|
||||
self._safe_set_text('profit_label', f"{profit:+.2f} PED")
|
||||
if hasattr(self, 'profit_label') and self.profit_label is not None:
|
||||
try:
|
||||
self.profit_label.setStyleSheet(f"font-size: 18px; font-weight: bold; color: {color};")
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
# Return %
|
||||
if hasattr(self, 'return_label'):
|
||||
ret = self._stats.return_percentage
|
||||
if ret >= 100:
|
||||
color = "#7FFF7F"
|
||||
elif ret >= 90:
|
||||
color = "#FFFF7F"
|
||||
else:
|
||||
color = "#FF7F7F"
|
||||
self.return_label.setText(f"{ret:.1f}%")
|
||||
self.return_label.setStyleSheet(f"font-size: 16px; font-weight: bold; color: {color};")
|
||||
ret = self._stats.return_percentage
|
||||
if ret >= 100:
|
||||
color = "#7FFF7F"
|
||||
elif ret >= 90:
|
||||
color = "#FFFF7F"
|
||||
else:
|
||||
color = "#FF7F7F"
|
||||
self._safe_set_text('return_label', f"{ret:.1f}%")
|
||||
if hasattr(self, 'return_label') and self.return_label is not None:
|
||||
try:
|
||||
self.return_label.setStyleSheet(f"font-size: 16px; font-weight: bold; color: {color};")
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
# Total Cost + Loot
|
||||
if hasattr(self, 'total_cost_label'):
|
||||
self.total_cost_label.setText(f"Cost: {self._stats.cost_total:.2f}")
|
||||
if hasattr(self, 'total_loot_label'):
|
||||
self.total_loot_label.setText(f"Loot: {self._stats.loot_total:.2f}")
|
||||
self._safe_set_text('total_cost_label', f"Cost: {self._stats.cost_total:.2f}")
|
||||
self._safe_set_text('total_loot_label', f"Loot: {self._stats.loot_total:.2f}")
|
||||
|
||||
# Cost metrics
|
||||
if hasattr(self, 'cps_label'):
|
||||
self.cps_label.setText(f"Shot: {self._stats.cost_per_shot:.4f}")
|
||||
if hasattr(self, 'cph_label'):
|
||||
self.cph_label.setText(f"Hit: {self._stats.cost_per_hit:.4f}")
|
||||
if hasattr(self, 'cphl_label'):
|
||||
self.cphl_label.setText(f"Heal: {self._stats.cost_per_heal:.4f}")
|
||||
self._safe_set_text('cps_label', f"Shot: {self._stats.cost_per_shot:.4f}")
|
||||
self._safe_set_text('cph_label', f"Hit: {self._stats.cost_per_hit:.4f}")
|
||||
self._safe_set_text('cphl_label', f"Heal: {self._stats.cost_per_heal:.4f}")
|
||||
|
||||
# Gear
|
||||
if hasattr(self, 'weapon_label'):
|
||||
self.weapon_label.setText(f"🔫 {self._stats.current_weapon[:20]}")
|
||||
if hasattr(self, 'armor_label'):
|
||||
self.armor_label.setText(f"🛡️ {self._stats.current_armor[:20]}")
|
||||
if hasattr(self, 'loadout_label'):
|
||||
self.loadout_label.setText(f"📋 {self._stats.current_loadout[:20]}")
|
||||
self._safe_set_text('weapon_label', f"🔫 {self._stats.current_weapon[:20]}")
|
||||
self._safe_set_text('armor_label', f"🛡️ {self._stats.current_armor[:20]}")
|
||||
self._safe_set_text('loadout_label', f"📋 {self._stats.current_loadout[:20]}")
|
||||
|
||||
# Cost breakdown
|
||||
if hasattr(self, 'wep_cost_label'):
|
||||
self.wep_cost_label.setText(f"{self._stats.weapon_cost_total:.2f}")
|
||||
if hasattr(self, 'arm_cost_label'):
|
||||
self.arm_cost_label.setText(f"{self._stats.armor_cost_total:.2f}")
|
||||
if hasattr(self, 'heal_cost_label'):
|
||||
self.heal_cost_label.setText(f"{self._stats.healing_cost_total:.2f}")
|
||||
self._safe_set_text('wep_cost_label', f"{self._stats.weapon_cost_total:.2f}")
|
||||
self._safe_set_text('arm_cost_label', f"{self._stats.armor_cost_total:.2f}")
|
||||
self._safe_set_text('heal_cost_label', f"{self._stats.healing_cost_total:.2f}")
|
||||
|
||||
# Combat
|
||||
if hasattr(self, 'kills_label'):
|
||||
self.kills_label.setText(f"Kills: {self._stats.kills}")
|
||||
if hasattr(self, 'globals_label'):
|
||||
self.globals_label.setText(f"Globals: {self._stats.globals_count}")
|
||||
self._safe_set_text('kills_label', f"Kills: {self._stats.kills}")
|
||||
self._safe_set_text('globals_label', f"Globals: {self._stats.globals_count}")
|
||||
|
||||
# Damage stats
|
||||
if hasattr(self, 'damage_dealt_label'):
|
||||
self.damage_dealt_label.setText(f"Dealt: {int(self._stats.damage_dealt)}")
|
||||
if hasattr(self, 'damage_taken_label'):
|
||||
self.damage_taken_label.setText(f"Taken: {int(self._stats.damage_taken)}")
|
||||
self._safe_set_text('damage_dealt_label', f"Dealt: {int(self._stats.damage_dealt)}")
|
||||
self._safe_set_text('damage_taken_label', f"Taken: {int(self._stats.damage_taken)}")
|
||||
|
||||
# Shrapnel
|
||||
if hasattr(self, 'shrapnel_label'):
|
||||
self.shrapnel_label.setText(f"💎 Shrapnel: {self._stats.shrapnel_total:.2f} PED")
|
||||
self._safe_set_text('shrapnel_label', f"💎 Shrapnel: {self._stats.shrapnel_total:.2f} PED")
|
||||
|
||||
# === Public Update Methods ===
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue