Reiter selbst gebaut - clam liess den ruhenden nicht dunkel werden
Sein Fund, zweimal: "er hebt den aktiven tab nicht hervor, der inaktive ist der
hervorgehobene". Gemessen statt geraten: der clam-Standard faerbt die
Reiterflaeche #bab5ab, und weder background noch lightcolor/darkcolor haben das
im laufenden Fenster zuverlaessig ueberschrieben.
Statt weiter daran zu drehen ist die Leiste jetzt selbst gebaut (reiter.py) -
und sieht dabei aus wie die Reiter in seinen Web-Oberflaechen: flacher Knopf,
der offene in Akzentfarbe, fett, mit Balken darunter und der Flaeche der Kachel.
Nach aussen verhaelt sie sich wie ein Notebook: add, select, index("current"/
"end"), tab(i, "text") und <<NotebookTabChanged>>. Deshalb bleiben der
Storno-Weg (korrektur.py waehlt select(1)) und pruef_montage unveraendert -
alle 14 Pruefstaende gruen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax
This commit is contained in:
parent
2e3a191f19
commit
1c2b115108
3 changed files with 112 additions and 6 deletions
12
app.py
12
app.py
|
|
@ -39,6 +39,7 @@ from bestand import (hoechster_zaehler_im_ordner, naechste_freie_nummer,
|
|||
vorhandene_rechnungen)
|
||||
from einzelinstanz import (eigene_pid_merken, einzelinstanz_pruefen, fenster_nach_vorn,
|
||||
laufende_pid_lesen)
|
||||
import reiter
|
||||
import theme
|
||||
from theme import MeldungMixin, ThemeMixin
|
||||
from korrektur import KorrekturMixin
|
||||
|
|
@ -374,13 +375,16 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin,
|
|||
# Leistungskatalog und die Montage-Rechnung mit der Monatsmiete. Der
|
||||
# Kopf (Kunde, Nummer, Datum, Zeitraum) und die Summenleiste gelten fuer
|
||||
# beide - nur die Mitte wechselt. So tippt niemand den Kunden zweimal.
|
||||
self.blaetter = ttk.Notebook(self)
|
||||
self.blaetter.pack(side="top", fill="both", expand=True, padx=12, pady=4)
|
||||
# Eigene Reiterleiste statt ttk.Notebook: unter clam liess sich der
|
||||
# ruhende Reiter nicht dunkel bekommen, er sah aus wie der offene.
|
||||
# Nach aussen verhaelt sie sich wie ein Notebook (siehe reiter.py).
|
||||
self.blaetter = reiter.Reiterleiste(self, farben=self)
|
||||
self.blaetter.pack(side="top", fill="both", expand=True, padx=16, pady=(4, 6))
|
||||
self.blaetter.bind("<<NotebookTabChanged>>", lambda _e: self._blatt_gewechselt())
|
||||
|
||||
camping = ttk.Frame(self.blaetter, padding=(2, 4))
|
||||
camping = ttk.Frame(self.blaetter.bereich, padding=(2, 6))
|
||||
self.blaetter.add(camping, text=" Campingrechnung ")
|
||||
montage_tab = ttk.Frame(self.blaetter, padding=(10, 10))
|
||||
montage_tab = ttk.Frame(self.blaetter.bereich, padding=(14, 14))
|
||||
self.blaetter.add(montage_tab, text=" Montage ")
|
||||
self._build_montage(montage_tab)
|
||||
|
||||
|
|
|
|||
94
reiter.py
Normal file
94
reiter.py
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
# -*- 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
|
||||
`<<NotebookTabChanged>>` 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("<Button-1>", lambda _e, i=nr: self.select(i))
|
||||
knopf.bind("<Enter>", lambda _e, i=nr: self._schweben(i, True))
|
||||
knopf.bind("<Leave>", 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("<<NotebookTabChanged>>")
|
||||
|
||||
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)
|
||||
12
theme.py
12
theme.py
|
|
@ -268,12 +268,20 @@ class ThemeMixin:
|
|||
# Der OFFENE Reiter gehoert zur Kachel darunter und ist deshalb heller
|
||||
# als die ruhenden. Vorher war es andersherum: die ruhenden lagen auf der
|
||||
# helleren Flaeche und sahen aus, als waeren sie ausgewaehlt.
|
||||
style.configure("TNotebook.Tab", background=bg,
|
||||
# ⚠️ clam zeichnet die Reiterflaeche aus lightcolor/darkcolor, nicht aus
|
||||
# background allein - werden die nicht mitgesetzt, bleibt der ruhende
|
||||
# Reiter hell und sieht aus wie der ausgewaehlte.
|
||||
style.configure("TNotebook.Tab", background=bg, lightcolor=bg, darkcolor=bg,
|
||||
foreground=self.col_muted, bordercolor=self.col_line,
|
||||
padding=(20, 9), font=(SCHRIFT_NAME, 10), borderwidth=0)
|
||||
padding=(20, 9), font=(SCHRIFT_NAME, 10), borderwidth=1)
|
||||
style.map("TNotebook.Tab",
|
||||
background=[("selected", self.col_card),
|
||||
("active", mischen(accent, bg, 0.12))],
|
||||
lightcolor=[("selected", self.col_card),
|
||||
("active", mischen(accent, bg, 0.12))],
|
||||
darkcolor=[("selected", self.col_card),
|
||||
("active", mischen(accent, bg, 0.12))],
|
||||
bordercolor=[("selected", accent)],
|
||||
foreground=[("selected", accent), ("active", fg)],
|
||||
font=[("selected", (SCHRIFT_NAME, 10, "bold"))])
|
||||
# Kein expand beim ausgewaehlten Reiter: er wuchs dadurch um ein paar
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue