Aktuální popis Tkinter GUI propojeného s BLE backendem, vícevláknovým řízením, historií a grafy.
Aplikace tvoří kompletní řídicí rozhraní pro balancer LTC3300-2. Součásti systému:
Aplikace používá dva typy grafů: mini-grafy (krátká historie) a velký graf (full history).
| Modul | Účel |
|---|---|
| ui_radiobuttons | Vytváří radiobuttony, poskytuje callback, umožňuje jejich změny z programu |
| ui_rectangles | Barevné obdélníky + legenda barev |
| ui_entries | Vstupní pole a historie v 2. řádku |
| ui_buttons | Tlačítka Run/Send + jejich vizuální indikace |
| ui_checkbuttons | Filtrace grafu – zapínání/vypínání jednotlivých křivek |
| ui_plots | Mini grafy + full-history graf, aktualizace |
| Ble.py | Asynchronní BLE komunikace, zpracování GATT notifikací |
| thread_worker.py | Worker thread – doplňkové logiky a reakce na události |
| gui_helpers | Zpracování fronty → bezpečný výpis do GUI |
| globals.py | Ukládá sdílené stavy jako user_changed_radio, lower_than_3... |
| my_tools.py | RAM-disk soubory, Sresp a Uresp parser, ukládání CSV |
Aplikace nově používá dva oddělené Queue objekty:
GUI zpracovává fronty pomocí:
process_queue(root, text, queue_to_main, queue_from_main)
Tím je zajištěna úplná separace toků zpráv.
ble_thread = threading.Thread(
target=lambda: start_call_ble(ADDRESS, queue_to_main)
)
ble_thread.start()
thread = threading.Thread(
target=run_periodically,
args=(5, '1', radio_vars),
daemon=True
)
thread.start()
Th_work_start(queue_to_main, queue_from_main)
Toto vlákno komunikuje přes obě fronty a provádí pomocné logiky.
Bezpečné ukončení
stop_event.set()
stop_call_ble()
Th_work_stop()
root.destroy()
GUI inicializuje:
Kritická část: GUI komponenty musí být vytvořeny v hlavním vlákně Tkinteru.
Radiobuttony slouží jako vstupní stavové hodnoty (0-4). Nová logika:
def radio_event_handler(row, value):
if Initialized < 2:
return
if not globals.not_user_changed_radio:
globals.user_changed_radio = True
set_send_button_color(True)
Přijaté hodnoty Sresp mohou radiobuttony přepsat:
radio_vars[i].set(v)
ui.on_radio_change(i, v)
set_rectangle_color(i, v)
historyU = [deque(maxlen=100) for _ in range(7)]
init_plots(frame_plots, historyU)
update_plots(historyU)
fig_full_history, axes_full_history = init_full_history_plot(historyU)
canvas_full_history = FigureCanvasTkAgg(fig, master=frame)
update_full_history_plot(historyU, canvas_full_history)
create_checkbuttons(root, historyU, canvas_full_history)
Funkce run_periodically běží každých 5 sekund.
Fáze:
create_file_to_send('S')
RunProcess = -1
values = DataFromSresp(...)
radio_vars[i].set(...)
set_rectangle_color(...)
valuesU = DataFromUresp(historyU)
lower_than_3 = any(v < 3.200 ...)
higher_than_4_2 = any(v > 4.200 ...)
root.after(0, set_entries)
update_plots(...)
update_full_history_plot(...)
save_full_state_to_csv(...)
Th_set_history(historyU)
Start Tkinter GUI
↓
Vytvoření obdélníků, entry, radiobuttonů, grafů, checkbuttonů
↓
Spuštění BLE vlákna
↓
Spuštění worker threadu
↓
Spuštění periodického vlákna
↓
Každých 5 sekund:
- odešli S → načti → aktualizuj radiobuttony + barvy
- odešli U → načti → aktualizuj hodnoty + grafy
↓
Uživatel může měnit radiobuttony → aktivuje tlačítko Send
↓
Kliknutí Run/Send zapisuje příkaz do RAM disk souboru
↓
Zavření okna → stop_event → ukončení všech vláken
Následující schéma zobrazuje kompletní architekturu main.py –
včetně GUI vlákna (Tkinter), BLE vlákna, worker vlákna, obousměrných front a
hlavní smyčky run_periodically() s řízením stavů
RunProcess = 1 → -1 → 2 → -2 → 1….