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 feelingsacausesze 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.colorsa- self.colors_darkobsahují syté barvy a jejich tmavé varianty pro posuvník.
- self.pastel_colors_lighta- self.pastel_colors_darkobsahují pastelové odstíny, které se použijí při klikání na tlačítko.
 
- Scrollable frame:
- V metodě create_emotion_widgetsvytvoří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_buttoncyklí hodnoty stavu a mění barvy tlačítka podle pastelových barev.
- Funkce emotion_slider_updateaktualizuje 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