Níže najdeš kompletní příklad, který:
• Načte možnosti (pocity a příčiny) ze souboru options.json
• Vytvoří scrollovatelnou oblast, ve které pro každý pocit (z načteného seznamu) vytvoří podřízený frame
• V každém podřízeném frame je umístěn:
- Label s názvem pocitu (vlevo)
- Label zobrazující hodnotu posuvníku (intenzitu)
- Horizontální posuvník, který nastaví číselnou hodnotu (syté barvy – definované v self.colors a self.colors_dark)
- Na pravé straně je tlačítko (vytvořené funkcí create_toggle_button), které při kliknutí přepíná stav podle sekvence indexů [0, 2, 5, 7, 9] a mění svou barvu na pastelové odstíny (definované v self.pastel_colors_light a self.pastel_colors_dark)
Níže je uvedený kód:
import datetime
import json
import tkinter as tk
from tkinter import ttk
DATA_FILE = "emotions_data.json"
OPTIONS_FILE = "options.json"
COLOR_WHEEL = True
TIME_MAPPING = {
0: "t-5h", 1: "6-10h", 2: "11-12h", 3: "13-14h",
4: "15-16h", 5: "17-19h", 6: "20-0h", 7: "1h-t"
}
PHARMATICS = {
0: "Agomelatin (nová látka)", 1: "Amitriptylin (TCA)", 2: "Bupropion (NDRI)",
3: "Carbamazepin (tymoprofilaktika)", 4: "Citalopram (SSRI)", 5: "Clomipramin (TCA)",
6: "Duloxetin (SNRI)", 7: "Dibenzepin (2. generace)", 8: "Escitalopram (SSRI)",
9: "Fluoxetin (SSRI)", 10: "Fluvoxamin (SSRI)", 11: "Lamotrigin (tymoprofilaktika)",
12: "Lithium carbonicum (tymoprofilaktika)", 13: "Mianserin (2. generace)",
14: "Milnacipran (SNRI)", 15: "Mirtazapin (NASSA)", 16: "Moclobemid (RIMA)",
17: "Nortriptylin (TCA)", 18: "Paroxetin (SSRI)", 19: "Sertralin (SSRI)",
20: "Tianeptin (samostatný přípravek)", 21: "Trittico (SARI)",
22: "Valproát (tymoprofilaktika)", 23: "Venlafaxin (SNRI)"
}
class MoodTrackerApp:
def __init__(self, root):
self.root = root
self.root.title("Mood Tracker")
# Načtení možností (feelings, causes) ze souboru options.json
try:
with open(OPTIONS_FILE, "r", encoding="utf-8") as file:
options = json.load(file)
self.feelings = options.get("feelings", ["Smutek", "Beznaděj", "Stres", "Úzkost", "Bolest", "Deprese"])
self.causes = options.get("causes", [
"Někdo mi něco špatného řekl",
"Někdo mě kritizoval, hodnotil, nebo káral",
"Vyřizoval jsem nějakou běžnou záležitost",
"Nastala konfliktní situace",
"Hádka",
"Postraumatická reakce",
"Posttraumatický syndrom nebo Posttraumatická porucha",
"Mohou za to léky",
"Jiná možnost"
])
except (FileNotFoundError, json.JSONDecodeError):
self.feelings = ["Smutek", "Beznaděj", "Stres", "Úzkost", "Bolest", "Deprese"]
self.causes = [
"Někdo mi něco špatného řekl",
"Někdo mě kritizoval, hodnotil, nebo káral",
"Vyřizoval jsem nějakou běžnou záležitost",
"Nastala konfliktní situace",
"Hádka",
"Postraumatická reakce",
"Posttraumatický syndrom nebo Posttraumatická porucha",
"Mohou za to léky",
"Jiná možnost"
]
# Definice barevných slovníků
# Syté barvy
self.colors = {
0: "#00FF00", # Čistá zelená (lime)
1: "#66FF00",
2: "#CCFF00",
3: "#FFFF00",
4: "#FFCC00",
5: "#FF6600",
6: "#FF4D00",
7: "#FF3300",
8: "#FF1A00",
9: "#FF0D00",
10: "#FF0000"
}
self.colors_dark = {
0: "#009900",
1: "#339900",
2: "#999900",
3: "#CCCC00",
4: "#CC9900",
5: "#CC3300",
6: "#CC2A00",
7: "#CC2200",
8: "#CC1A00",
9: "#CC0F00",
10: "#CC0000"
}
# Pastelové barvy (při klikání na tlačítko)
self.pastel_colors_light = {
0: "#A8E6A3",
2: "#D7F59D",
5: "#FFB27D",
7: "#FF9280",
9: "#FF8080"
}
self.pastel_colors_dark = {
0: "#658A62",
2: "#81935E",
5: "#996B4B",
7: "#99574D",
9: "#994D4D"
}
self.init_styles()
self.create_widgets()
self.create_emotion_widgets()
def init_styles(self):
style = ttk.Style(self.root)
style.configure("Toggle.TButton", foreground="darkgray", padding=2)
style.configure("Toggle.On.TButton", foreground="#354A59", padding=2)
style.configure("Feeling.TButton", foreground=self.colors[0], padding=2)
def create_widgets(self):
# Další widgety (např. čas, léky, atd.) lze přidat sem.
# Pro tento příklad se zaměřujeme především na scrollovatelnou oblast pro emoce.
pass
def create_emotion_widgets(self):
# Vytvoříme scrollovatelný frame pro pocity
canvas = tk.Canvas(self.root)
scrollbar = ttk.Scrollbar(self.root, orient="vertical", command=canvas.yview)
self.scrollable_frame = ttk.Frame(canvas)
self.scrollable_frame.bind(
"<Configure>",
lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
)
canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
canvas.configure(yscrollcommand=scrollbar.set)
canvas.pack(side="left", fill="both", expand=True)
scrollbar.pack(side="right", fill="y")
# Dictionaries pro uchovávání proměnných pro jednotlivé emoce
self.feelings_vars = {} # Stav (toggle) pro konkrétní emoci
self.feelings_intensity_vars = {} # Intenzita (posuvník) pro konkrétní emoci
# Pro každou emoci vytvoříme frame s widgety:
for feeling in self.feelings:
feeling_frame = ttk.Frame(self.scrollable_frame)
feeling_frame.pack(fill="x", pady=5, padx=5)
# Label s názvem emoce
ttk.Label(feeling_frame, text=feeling).pack(side="left", padx=5)
# Proměnná pro toggle stav (0, 2, 5, 7, 9)
var = tk.IntVar(value=0)
self.feelings_vars[feeling] = var
# Tlačítko, které přepíná stav emoce (toggle button)
toggle_btn = self.create_toggle_button(feeling_frame, var)
toggle_btn.pack(side="right", padx=5)
# Proměnná pro intenzitu emoce a posuvník
intensity_var = tk.IntVar(value=0)
self.feelings_intensity_vars[feeling] = intensity_var
# Label zobrazující číselnou hodnotu intenzity
intensity_label = ttk.Label(feeling_frame, textvariable=intensity_var, width=3)
intensity_label.pack(side="right", padx=5)
# Horizontální posuvník pro intenzitu emoce
intensity_slider = ttk.Scale(
feeling_frame, from_=0, to=10, variable=intensity_var,
orient="horizontal", length=150,
command=lambda val, f=feeling: self.emotion_slider_update(f, val)
)
intensity_slider.pack(side="right", padx=5)
def create_toggle_button(self, master, variable, width=4):
"""
Vytvoří toggle tlačítko, které při kliknutí cyklí hodnoty v seznamu [0, 2, 5, 7, 9]
a nastaví barvu tlačítka pomocí pastelových barev.
"""
btn = tk.Button(master, text="•", font=("Arial", 42), bd=5, command=lambda: self.toggle_feeling_button(btn, variable))
# Inicializace – nastavíme počáteční pastelovou barvu pro stav 0
initial_light = self.pastel_colors_light.get(0, "#A8E6A3")
initial_dark = self.pastel_colors_dark.get(0, "#658A62")
btn.config(bg=initial_dark, fg=initial_light, activebackground=initial_light, activeforeground=initial_dark)
return btn
def toggle_feeling_button(self, btn, variable):
"""Při kliknutí na tlačítko cyklí hodnoty a aktualizuje barvu podle pastelových barev."""
states = [0, 2, 5, 7, 9]
current = variable.get()
new_index = (states.index(current) + 1) % len(states)
new_state = states[new_index]
variable.set(new_state)
pastel_light = self.pastel_colors_light.get(new_state, "#A8E6A3")
pastel_dark = self.pastel_colors_dark.get(new_state, "#658A62")
btn.config(bg=pastel_dark, fg=pastel_light, activebackground=pastel_light, activeforeground=pastel_dark)
def emotion_slider_update(self, feeling, value):
"""
Aktualizuje barvu tlačítka u dané emoce na základě hodnoty posuvníku.
Používá syté barvy (self.colors a self.colors_dark).
"""
intensity = int(float(value))
color_light = self.colors.get(intensity, "#FFFFFF")
color_dark = self.colors_dark.get(intensity, "#000000")
# Projdeme widgety v rámci příslušného frame a nalezneme tlačítko
for child in self.scrollable_frame.winfo_children():
# Předpokládáme, že první widget v rámci frame je Label s názvem emoce
lbl = child.winfo_children()[0]
if lbl.cget("text") == feeling:
# Projdeme widgety v daném frame, hledáme tlačítko
for widget in child.winfo_children():
if isinstance(widget, tk.Button):
widget.config(bg=color_dark, fg=color_light, activebackground=color_light, activeforeground=color_dark)
break
break
def load_options(self):
# V tomto příkladu načítáme pouze "Pravidelný čas" z options.json, pokud je potřeba rozšířit, použijte self.feelings a self.causes.
try:
with open(OPTIONS_FILE, "r", encoding="utf-8") as file:
options = json.load(file)
# Například, pokud je v souboru klíč "Pravidelný čas":
self.meds_time = options.get("Pravidelný čas", "7:00")
except (FileNotFoundError, json.JSONDecodeError):
self.meds_time = "7:00"
def on_time_edit(self, event):
pass # Implementace pro úpravu času, pokud je potřeba
if __name__ == "__main__":
root = tk.Tk()
root.geometry("400x800")
app = MoodTrackerApp(root)
root.mainloop()
Vysvětlení:
- Načítání možností:
- V konstruktoru se pokoušíme načíst
feelings
acauses
ze souboru options.json. Pokud se načtení nezdaří, jsou použity výchozí hodnoty.
- V konstruktoru se pokoušíme načíst
- Barevné slovníky:
self.colors
aself.colors_dark
obsahují syté barvy a jejich tmavé varianty pro posuvník.self.pastel_colors_light
aself.pastel_colors_dark
obsahují pastelové odstíny, které se použijí při klikání na tlačítko.
- Scrollable frame:
- V metodě
create_emotion_widgets
vytvoříme scrollovatelný canvas, do kterého umístíme frame se všemi emocemi.
- V metodě
- Pro každou emoci:
- Vytvoří se frame s label, posuvníkem, label pro zobrazení hodnoty a tlačítkem (toggle).
- Tlačítko se vytváří funkcí
create_toggle_button
, která nastaví počáteční pastelové barvy. - Funkce
toggle_feeling_button
cyklí hodnoty stavu a mění barvy tlačítka podle pastelových barev. - Funkce
emotion_slider_update
aktualizuje barvy tlačítka pomocí sytých barev, pokud se posuvník pohne.
Tato implementace by měla odpovídat tvému zadání – scrollovatelná oblast s horizontálními posuvníky pro jednotlivé emoce a vedle nich tlačítka, která mění barvu při kliknutí i při změně hodnoty posuvníku.
Dej vědět, jestli je třeba něco upravit nebo doplnit!
Žádné komentáře:
Okomentovat