Eigene Kennungen ausblenden, Win95-Menüs, verschiebbares Hauptfenster bei offenem Dialog u. a.
Windows-Build / windows-exe (push) Canceled after 53m28s
Windows-Build / windows-exe (push) Canceled after 53m28s
Neu: - Eigene Kennungen (eigene Filiale) ausblenden: nicht angezeigt, nicht mitgerechnet, nicht exportiert; per Rechtsklick, Händler-Menü oder Import-Bericht; Händler-Zuordnung hat Vorrang - Menüs im Win95-Stil: wechseln beim Überfahren der Menüleiste, Tastatur, Kontextmenü gleich - Dialoge sperren nur den Inhalt: Hauptfenster bleibt verschiebbar/maximierbar; Dialoge haben eigenen Taskleisten-Eintrag; Klick auf gesperrten Inhalt holt den Dialog nach vorn (blinkt) - Trennlinie zwischen Händler- und Positionsliste sichtbar und ziehbar, Position wird gemerkt - Strg+Rücktaste / Strg+Entf löschen ganze Wörter in allen Eingabefeldern Behoben: - Gedrückte Knöpfe zeigten keine Beschriftung (activeForeground gehört in Tk zur Klasse Background) - Tipp des Tages: Text lief aus dem sichtbaren Bereich - Größenänderung: breiterer Griffbereich mit Ecken, Zeiger wird zuverlässig zurückgesetzt, flüssiger; Verschieben über Windows selbst (inkl. Andocken), Minimieren über Windows - Zeichen, die MS Sans Serif nicht hat (…, ▸, →, •), durch Win95-übliche ersetzt - Menü/Tooltip/Dialog: Größe+Position zusammen setzen (Tk ignoriert sonst die Position) - Suche reagiert erst nach kurzer Tipp-Pause (flüssigeres Tippen) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
69c2a108a9
commit
807a38622c
15 files changed
+1217
-187
No files matched your search
@@ -0,0 +1,93 @@
|
||||
"""Modale Sperre ohne Tk-„grab“: Nur der INHALT des aufrufenden Fensters wird gesperrt.
|
||||
|
||||
Titelleiste und Rand bleiben bedienbar – das Hauptfenster lässt sich also verschieben, maximieren
|
||||
und in der Größe ändern, während ein Dialog offen ist. Klickt man auf den gesperrten Inhalt, kommt
|
||||
der Dialog nach vorn und blinkt kurz (wie bei Windows).
|
||||
|
||||
Technik: Jedes Widget im gesperrten Bereich bekommt vorn das Bindungs-Tag ``Pm95Gesperrt``. Dessen
|
||||
Bindungen laufen vor allen anderen und beenden Klicks/Tastendrücke mit „break“.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import tkinter as tk
|
||||
|
||||
TAG = "Pm95Gesperrt"
|
||||
_stapel: list[tk.Toplevel] = [] # offene modale Fenster, innerstes zuletzt
|
||||
|
||||
GESPERRTE_EREIGNISSE = ("<ButtonPress>", "<ButtonRelease>", "<Double-ButtonPress>", "<Triple-ButtonPress>",
|
||||
"<B1-Motion>", "<KeyPress>", "<KeyRelease>", "<MouseWheel>")
|
||||
|
||||
|
||||
def oberstes() -> tk.Toplevel | None:
|
||||
"""Das zuletzt geöffnete, noch offene modale Fenster (oder None)."""
|
||||
while _stapel:
|
||||
d = _stapel[-1]
|
||||
try:
|
||||
if d.winfo_exists():
|
||||
return d
|
||||
except tk.TclError:
|
||||
pass
|
||||
_stapel.pop()
|
||||
return None
|
||||
|
||||
|
||||
def offen() -> bool:
|
||||
return oberstes() is not None
|
||||
|
||||
|
||||
def _gesperrt_geklickt(event):
|
||||
d = oberstes()
|
||||
if d is not None and hasattr(d, "nach_vorn"):
|
||||
d.nach_vorn(blinken=str(event.type) in ("ButtonPress", "4"))
|
||||
return "break"
|
||||
|
||||
|
||||
def _einrichten(root: tk.Misc):
|
||||
# Merker am Tk-Objekt selbst (nicht am Namen: das Hauptfenster heißt in jeder Tk-Instanz „.“)
|
||||
if getattr(root, "_pm95_sperre_eingerichtet", False):
|
||||
return
|
||||
for seq in GESPERRTE_EREIGNISSE:
|
||||
root.bind_class(TAG, seq, _gesperrt_geklickt)
|
||||
root._pm95_sperre_eingerichtet = True
|
||||
|
||||
|
||||
def sperrbereiche(fenster: tk.Misc) -> list[tk.Misc]:
|
||||
"""Welche Widgets eines Fensters gesperrt werden: alles außer Titelleiste (und Rand)."""
|
||||
eigene = getattr(fenster, "sperrbereich", None)
|
||||
if callable(eigene):
|
||||
return list(eigene())
|
||||
titel = getattr(fenster, "titelleiste", None)
|
||||
return [k for k in fenster.winfo_children() if k is not titel and not isinstance(k, tk.Toplevel)]
|
||||
|
||||
|
||||
class Sperre:
|
||||
"""Sperrt den Inhalt von `fenster`, solange `dialog` offen ist."""
|
||||
|
||||
def __init__(self, fenster: tk.Misc, dialog: tk.Toplevel):
|
||||
_einrichten(fenster._root())
|
||||
self.widgets: list[tk.Misc] = []
|
||||
for bereich in sperrbereiche(fenster):
|
||||
self._sperren(bereich)
|
||||
_stapel.append(dialog)
|
||||
self.dialog = dialog
|
||||
|
||||
def _sperren(self, w: tk.Misc):
|
||||
if isinstance(w, tk.Toplevel):
|
||||
return # eigene Fenster (z. B. andere Dialoge) nicht anfassen
|
||||
tags = w.bindtags()
|
||||
if TAG not in tags:
|
||||
w.bindtags((TAG,) + tuple(tags))
|
||||
self.widgets.append(w)
|
||||
for kind in w.winfo_children():
|
||||
self._sperren(kind)
|
||||
|
||||
def aufheben(self):
|
||||
for w in self.widgets:
|
||||
try:
|
||||
if w.winfo_exists():
|
||||
w.bindtags(tuple(t for t in w.bindtags() if t != TAG))
|
||||
except tk.TclError:
|
||||
pass
|
||||
self.widgets = []
|
||||
if self.dialog in _stapel:
|
||||
_stapel.remove(self.dialog)
|
||||
Reference in new issue
Block a user