# -*- coding: utf-8 -*- """Reiterleiste im Pcore-Stil: Knopf mit Unterstrich statt ttk-Karteikarte. WARUM NICHT ttk.Notebook ------------------------ Unter dem clam-Thema laesst sich die Reiterflaeche nicht zuverlaessig einfaerben: der RUHENDE Reiter blieb hell und sah aus wie der ausgewaehlte - also genau verkehrt herum. Sein Fund: *"er hebt den aktiven tab nicht hervor, der inaktive ist der hervorgehobene"*. Statt weiter an clam zu drehen, ist die Leiste hier selbst gebaut - und sieht dabei aus wie die Reiter in seinen Web-Oberflaechen: ein flacher Knopf, der offene in Akzentfarbe mit einem Balken darunter. NACH AUSSEN wie ein Notebook ---------------------------- `add`, `select`, `index("current"/"end")`, `tab(i, "text")` und das Ereignis `<>` verhalten sich wie beim Original. So bleiben die Aufrufer unveraendert - der Storno-Weg waehlt weiter `select(1)`, und die Pruefstaende lesen die Reiternamen wie bisher. """ import tkinter as tk from tkinter import ttk import theme class Reiterleiste(ttk.Frame): def __init__(self, master, farben=None): super().__init__(master) self.f = farben if farben is not None else master self._seiten = [] # (Rahmen, Text, Knopf, Balken) self._aktiv = 0 self.leiste = ttk.Frame(self) self.leiste.pack(side="top", fill="x") self.bereich = ttk.Frame(self) self.bereich.pack(side="top", fill="both", expand=True) # ---- wie beim Notebook ------------------------------------------------ def add(self, rahmen, text=""): nr = len(self._seiten) kasten = ttk.Frame(self.leiste) kasten.pack(side="left", padx=(0, 4)) knopf = tk.Label(kasten, text=text.strip(), cursor="hand2", bg=self.f.col_bg, fg=self.f.col_muted, font=(theme.SCHRIFT_NAME, 10), padx=18, pady=8) knopf.pack(side="top", fill="x") # Der Balken unter dem offenen Reiter - dasselbe Zeichen wie in den # Web-Oberflaechen. balken = tk.Frame(kasten, height=2, bg=self.f.col_bg) balken.pack(side="top", fill="x") knopf.bind("", lambda _e, i=nr: self.select(i)) knopf.bind("", lambda _e, i=nr: self._schweben(i, True)) knopf.bind("", lambda _e, i=nr: self._schweben(i, False)) self._seiten.append([rahmen, text, knopf, balken]) if nr == 0: rahmen.pack(in_=self.bereich, fill="both", expand=True) self._zeichnen() def select(self, nr): nr = int(nr) if not (0 <= nr < len(self._seiten)) or nr == self._aktiv: self._zeichnen() return self._seiten[self._aktiv][0].pack_forget() self._aktiv = nr self._seiten[nr][0].pack(in_=self.bereich, fill="both", expand=True) self._zeichnen() # Dasselbe Ereignis wie beim Notebook - die App haengt daran. self.event_generate("<>") def index(self, was="current"): return len(self._seiten) if was == "end" else self._aktiv def tab(self, nr, key="text"): return self._seiten[int(nr)][1] if key == "text" else "" # ---- Aussehen --------------------------------------------------------- def _schweben(self, nr, drueber): if nr == self._aktiv: return knopf = self._seiten[nr][2] knopf.configure(fg=self.f.col_fg if drueber else self.f.col_muted) def _zeichnen(self): for i, (_rahmen, _text, knopf, balken) in enumerate(self._seiten): offen = (i == self._aktiv) knopf.configure( fg=self.f.col_accent if offen else self.f.col_muted, bg=self.f.col_card if offen else self.f.col_bg, font=(theme.SCHRIFT_NAME, 10, "bold") if offen else (theme.SCHRIFT_NAME, 10)) balken.configure(bg=self.f.col_accent if offen else self.f.col_bg)