Skip to content

Commit 1d213bb

Browse files
theme
1 parent b3168ba commit 1d213bb

9 files changed

Lines changed: 145 additions & 54 deletions
198 Bytes
Binary file not shown.
1.59 KB
Binary file not shown.
0 Bytes
Binary file not shown.
58 Bytes
Binary file not shown.

controladores.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import platform
1212

1313
try:
14-
from tema_config import gerenciador_temas, obter_cores
14+
from tema_config import gerenciador_temas, obter_cores, obter_caminho_recurso # Importar obter_caminho_recurso
1515
CORES = obter_cores()
1616
except ImportError:
1717
class GerenciadorTemasFallback:
@@ -39,6 +39,9 @@ def obter_cores(self):
3939
}
4040
gerenciador_temas = GerenciadorTemasFallback()
4141
CORES = gerenciador_temas.obter_cores()
42+
def obter_caminho_recurso(nome_arquivo):
43+
return nome_arquivo
44+
4245

4346
# Importar componentes de métricas e exportação
4447
try:
@@ -97,7 +100,8 @@ def __init__(self, parent):
97100

98101
# Ícone (se disponível)
99102
try:
100-
self.iconbitmap(default='icon.ico')
103+
icon_path = obter_caminho_recurso('icon.ico') # Usar obter_caminho_recurso
104+
self.iconbitmap(default=icon_path)
101105
except:
102106
pass
103107

logger_sistema.py

Lines changed: 71 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import logging
77
import os
8+
import sys
89
from datetime import datetime
910
from pathlib import Path
1011

@@ -23,44 +24,79 @@ def __init__(self):
2324
if self._logger is None:
2425
self._setup_logger()
2526

27+
def _get_logs_directory(self):
28+
"""
29+
Obtém o diretório apropriado para logs baseado no ambiente
30+
"""
31+
if getattr(sys, 'frozen', False):
32+
# Running as executable
33+
if sys.platform == "win32":
34+
# Windows: Use AppData/Local
35+
appdata = os.getenv('LOCALAPPDATA') or os.getenv('APPDATA')
36+
if appdata:
37+
base_dir = Path(appdata) / "SistemaControle"
38+
else:
39+
base_dir = Path.home() / "SistemaControle"
40+
else:
41+
# Linux/Mac: Use home directory
42+
base_dir = Path.home() / ".sistemacontrole"
43+
else:
44+
# Running as script
45+
base_dir = Path(".")
46+
47+
logs_dir = base_dir / "logs"
48+
return logs_dir
49+
2650
def _setup_logger(self):
2751
"""Configura o logger com arquivo e console"""
28-
# Criar diretório de logs se não existir
29-
logs_dir = Path("logs")
30-
logs_dir.mkdir(exist_ok=True)
31-
32-
# Nome do arquivo com data
33-
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
34-
log_file = logs_dir / f"sistema_{timestamp}.log"
35-
36-
# Configurar logger
37-
self._logger = logging.getLogger("SistemaControle")
38-
self._logger.setLevel(logging.DEBUG)
39-
40-
# Remover handlers anteriores se existirem
41-
for handler in self._logger.handlers[:]:
42-
self._logger.removeHandler(handler)
43-
44-
# Formato detalhado
45-
formatter = logging.Formatter(
46-
'%(asctime)s - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s',
47-
datefmt='%Y-%m-%d %H:%M:%S'
48-
)
49-
50-
# Handler para arquivo
51-
file_handler = logging.FileHandler(log_file, encoding='utf-8')
52-
file_handler.setLevel(logging.DEBUG)
53-
file_handler.setFormatter(formatter)
54-
self._logger.addHandler(file_handler)
55-
56-
# Handler para console (apenas WARNING e acima)
57-
console_handler = logging.StreamHandler()
58-
console_handler.setLevel(logging.WARNING)
59-
console_formatter = logging.Formatter('%(levelname)s: %(message)s')
60-
console_handler.setFormatter(console_formatter)
61-
self._logger.addHandler(console_handler)
52+
try:
53+
# Criar diretório de logs se não existir
54+
logs_dir = self._get_logs_directory()
55+
logs_dir.mkdir(parents=True, exist_ok=True)
56+
57+
# Nome do arquivo com data
58+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
59+
log_file = logs_dir / f"sistema_{timestamp}.log"
60+
61+
# Configurar logger
62+
self._logger = logging.getLogger("SistemaControle")
63+
self._logger.setLevel(logging.DEBUG)
64+
65+
# Remover handlers anteriores se existirem
66+
for handler in self._logger.handlers[:]:
67+
self._logger.removeHandler(handler)
68+
69+
# Formato detalhado
70+
formatter = logging.Formatter(
71+
'%(asctime)s - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s',
72+
datefmt='%Y-%m-%d %H:%M:%S'
73+
)
74+
75+
# Handler para arquivo
76+
file_handler = logging.FileHandler(log_file, encoding='utf-8')
77+
file_handler.setLevel(logging.DEBUG)
78+
file_handler.setFormatter(formatter)
79+
self._logger.addHandler(file_handler)
80+
81+
# Handler para console (apenas WARNING e acima)
82+
console_handler = logging.StreamHandler()
83+
console_handler.setLevel(logging.WARNING)
84+
console_formatter = logging.Formatter('%(levelname)s: %(message)s')
85+
console_handler.setFormatter(console_formatter)
86+
self._logger.addHandler(console_handler)
87+
88+
self._logger.info(f"Logger iniciado com sucesso. Logs em: {logs_dir}")
6289

63-
self._logger.info("Logger iniciado com sucesso")
90+
except Exception as e:
91+
# Fallback: se falhar, usar apenas console
92+
self._logger = logging.getLogger("SistemaControle")
93+
self._logger.setLevel(logging.WARNING)
94+
console_handler = logging.StreamHandler()
95+
console_handler.setLevel(logging.WARNING)
96+
formatter = logging.Formatter('%(levelname)s: %(message)s')
97+
console_handler.setFormatter(formatter)
98+
self._logger.addHandler(console_handler)
99+
self._logger.warning(f"Não foi possível criar arquivo de log: {e}")
64100

65101
def get_logger(self):
66102
"""Retorna o logger configurado"""

tela.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from gerenciador_excecoes import gerenciador_excecoes, TipoErro, GerenciadorExcecoes # import exception handler
1919
from utilidades_ui import GerenciadorResponsividade, UtiliadadesGraficos # import UI utilities
2020
from lugar_geometrico_raizes import AnalisadorLGR, ErroValidacaoLGR
21-
from tema_config import GerenciadorTemas, gerenciador_temas
21+
from tema_config import GerenciadorTemas, gerenciador_temas, obter_caminho_recurso # Importar função para obter caminho de recursos
2222

2323
CORES = gerenciador_temas.obter_cores()
2424

@@ -95,7 +95,7 @@ class GerenciadorTemas:
9595

9696
def __init__(self):
9797
self.tema_atual = "dark"
98-
self.config_file = "config_tema.json"
98+
self.config_file = obter_caminho_recurso("config_tema.json") # Usar função para obter caminho
9999
self.carregar_configuracao()
100100

101101
def carregar_configuracao(self):
@@ -513,11 +513,13 @@ def set_window_icon(self):
513513
"""Define o ícone da janela de forma multiplataforma"""
514514
try:
515515
if self.config.is_windows:
516-
if os.path.exists("image/icons/papel.ico"):
517-
self.iconbitmap("image/icons/papel.ico")
516+
icon_path = obter_caminho_recurso("image/icons/papel.ico") # Usar obter_caminho_recurso
517+
if os.path.exists(icon_path):
518+
self.iconbitmap(icon_path)
518519
elif self.config.is_linux:
519-
if os.path.exists("image/icons/papel.ico"):
520-
icon = Image.open("image/icons/papel.ico")
520+
icon_path = obter_caminho_recurso("image/icons/papel.ico") # Usar obter_caminho_recurso
521+
if os.path.exists(icon_path):
522+
icon = Image.open(icon_path)
521523
photo = ImageTk.PhotoImage(icon)
522524
self.iconphoto(True, photo)
523525
elif self.config.is_mac:
@@ -626,8 +628,9 @@ def carregar_imagens(self):
626628
self.logo_image = None
627629

628630
try:
629-
if os.path.exists("logo.png"):
630-
img_pil = Image.open("logo.png").convert("RGBA")
631+
logo_path = obter_caminho_recurso("logo.png") # Usar obter_caminho_recurso
632+
if os.path.exists(logo_path):
633+
img_pil = Image.open(logo_path).convert("RGBA")
631634

632635
if self.screen_height <= 768:
633636
max_h_logo = 40

tema_config.py

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,25 @@
44
"""
55

66
import os
7+
import sys
78
import json
89

910

11+
def obter_caminho_recurso(nome_arquivo):
12+
"""
13+
Obtém o caminho correto para recursos tanto em desenvolvimento quanto no executável.
14+
PyInstaller cria uma pasta temporária e armazena o caminho em _MEIPASS
15+
"""
16+
try:
17+
# PyInstaller cria uma pasta temp e armazena o caminho em _MEIPASS
18+
base_path = sys._MEIPASS
19+
except AttributeError:
20+
# Se não estiver rodando como executável, usa o diretório atual
21+
base_path = os.path.abspath(".")
22+
23+
return os.path.join(base_path, nome_arquivo)
24+
25+
1026
class GerenciadorTemas:
1127
"""Gerencia temas claro e escuro com persistência"""
1228

@@ -75,26 +91,57 @@ class GerenciadorTemas:
7591

7692
def __init__(self):
7793
self.tema_atual = "dark"
78-
self.config_file = "config_tema.json"
94+
self.config_file = self._obter_caminho_config()
7995
self.carregar_configuracao()
8096

97+
def _obter_caminho_config(self):
98+
"""
99+
Obtém o caminho para o arquivo de configuração no diretório do usuário.
100+
Isso garante que as configurações persistam entre execuções.
101+
"""
102+
try:
103+
# Tenta usar o diretório do usuário
104+
if os.name == 'nt': # Windows
105+
base_dir = os.path.join(os.environ.get('APPDATA', os.path.expanduser('~')), 'SistemaControle')
106+
else: # Linux/Mac
107+
base_dir = os.path.join(os.path.expanduser('~'), '.sistemacontrole')
108+
109+
# Cria o diretório se não existir
110+
os.makedirs(base_dir, exist_ok=True)
111+
return os.path.join(base_dir, 'config_tema.json')
112+
except Exception:
113+
# Fallback para o diretório temporário
114+
import tempfile
115+
return os.path.join(tempfile.gettempdir(), 'sistemacontrole_config_tema.json')
116+
81117
def carregar_configuracao(self):
82118
"""Carrega configuração salva"""
83119
try:
84120
if os.path.exists(self.config_file):
85-
with open(self.config_file, 'r') as f:
121+
with open(self.config_file, 'r', encoding='utf-8') as f:
86122
config = json.load(f)
87-
self.tema_atual = config.get('tema', 'dark')
88-
except:
123+
tema_carregado = config.get('tema', 'dark')
124+
# Valida se o tema existe
125+
if tema_carregado in self.TEMAS:
126+
self.tema_atual = tema_carregado
127+
else:
128+
self.tema_atual = "dark"
129+
else:
130+
self.tema_atual = "dark"
131+
except Exception as e:
132+
print(f"[AVISO] Erro ao carregar configuração de tema: {e}")
89133
self.tema_atual = "dark"
90134

91135
def salvar_configuracao(self):
92136
"""Salva configuração atual"""
93137
try:
94-
with open(self.config_file, 'w') as f:
95-
json.dump({'tema': self.tema_atual}, f)
96-
except:
97-
pass
138+
# Garante que o diretório existe
139+
os.makedirs(os.path.dirname(self.config_file), exist_ok=True)
140+
141+
with open(self.config_file, 'w', encoding='utf-8') as f:
142+
json.dump({'tema': self.tema_atual}, f, indent=2)
143+
except Exception as e:
144+
print(f"[AVISO] Erro ao salvar configuração de tema: {e}")
98145

99146
def alternar_tema(self):
100147
"""Alterna entre temas"""
@@ -115,7 +162,7 @@ def definir_tema(self, nome_tema):
115162

116163
def obter_cores(self):
117164
"""Retorna as cores do tema atual"""
118-
return self.TEMAS[self.tema_atual]
165+
return self.TEMAS[self.tema_atual].copy()
119166

120167
def obter_nome_tema(self):
121168
"""Retorna nome amigável do tema"""

utilidades_ui.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import platform
1212
import tkinter as tk
1313
from typing import Callable
14+
from tema_config import obter_caminho_recurso
1415

1516

1617
# ==========================================================

0 commit comments

Comments
 (0)