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
+279
-21
@@ -61,6 +61,23 @@ class Lauf:
|
||||
# eine evtl. geöffnete Fehlermeldung schließen, damit der Test nicht hängt
|
||||
self.root.after(100, self._meldungen_zu)
|
||||
self.root.report_callback_exception = melden
|
||||
self._warten_bis_sichtbar()
|
||||
|
||||
def _warten_bis_sichtbar(self, sekunden: float = 8.0):
|
||||
"""Wie ein Mensch erst bedienen, wenn das Hauptfenster zu sehen ist: Unter Windows wird es beim
|
||||
Start für den Taskleisten-Eintrag kurz aus- und wieder eingeblendet (unter Wine langsamer)."""
|
||||
ende = time.time() + sekunden
|
||||
stabil = 0
|
||||
while time.time() < ende:
|
||||
try:
|
||||
self.root.update()
|
||||
sichtbar = self.root.winfo_viewable() and self.app.inhalt.winfo_height() > 50
|
||||
except tk.TclError:
|
||||
return
|
||||
stabil = stabil + 1 if sichtbar else 0
|
||||
if stabil >= 10: # ~0,1 s durchgehend sichtbar
|
||||
return
|
||||
time.sleep(0.01)
|
||||
|
||||
# ---------------------------------------------------------------- Zustand
|
||||
def lebt_sonst(self, text: str) -> str:
|
||||
@@ -155,6 +172,10 @@ class Lauf:
|
||||
time.sleep(0.01)
|
||||
self.uebrig = [s[2] for s in offen]
|
||||
|
||||
def diagnose(self) -> str:
|
||||
"""Für Fehlermeldungen: welche Schritte nicht liefen + alle gesammelten Fehler."""
|
||||
return f"nicht ausgeführt: {self.uebrig}\n" + "\n".join(self.fehler)
|
||||
|
||||
def schliessen_ueber_fenster(self):
|
||||
"""Wie Klick auf × / Taskleiste ▸ Fenster schließen (WM_DELETE_WINDOW)."""
|
||||
cmd = self.root.tk.call("wm", "protocol", self.root._w, "WM_DELETE_WINDOW")
|
||||
@@ -233,7 +254,7 @@ def test_alt_f4_im_assistent_fragt_und_schliesst_nur_assistent(home):
|
||||
(lambda: lauf.dialog(Einrichtungsassistent) is None, lambda: None, "Assistent ist zu"),
|
||||
])
|
||||
assert lauf.lebt, lauf.lebt_sonst("Programm darf nicht beendet werden")
|
||||
assert not lauf.uebrig, lauf.uebrig
|
||||
assert not lauf.uebrig, lauf.diagnose()
|
||||
assert lauf.app.settings.get("assistent_erledigt") is True
|
||||
lauf.pruefen()
|
||||
lauf.ende()
|
||||
@@ -342,7 +363,6 @@ def test_alt_f4_bevor_die_sperre_steht(lauf_mit_daten, monkeypatch):
|
||||
Zeichnen sind noch nicht fertig. Alt+F4 muss trotzdem nur den Dialog schließen."""
|
||||
from provtool.gui import win95 as w
|
||||
from provtool.gui.dialogs import InfoDialog
|
||||
monkeypatch.setattr(w.Dialog, "_sperre_setzen", lambda self, versuch=0: None) # keine Sperre
|
||||
monkeypatch.setattr(w.Dialog, "winfo_ismapped", lambda self: 0) # „noch nicht gezeichnet“
|
||||
lauf = lauf_mit_daten
|
||||
lauf.ablauf([
|
||||
@@ -353,7 +373,7 @@ def test_alt_f4_bevor_die_sperre_steht(lauf_mit_daten, monkeypatch):
|
||||
(lambda: lauf.dialog(InfoDialog) is None, lambda: None, "Dialog geschlossen"),
|
||||
], sekunden=8)
|
||||
assert lauf.lebt, lauf.lebt_sonst("Alt+F4 darf bei offenem Dialog nicht das ganze Programm beenden")
|
||||
assert not lauf.uebrig, lauf.uebrig
|
||||
assert not lauf.uebrig, lauf.diagnose()
|
||||
lauf.pruefen()
|
||||
|
||||
|
||||
@@ -367,7 +387,7 @@ def test_alt_f4_im_rundgang_beendet_nur_den_rundgang(lauf_mit_daten):
|
||||
(lambda: rg().blase is None and not rg().rahmen, lambda: None, "Rundgang samt Rahmen weg"),
|
||||
], sekunden=8)
|
||||
assert lauf.lebt, lauf.lebt_sonst("Alt+F4 im Rundgang darf nicht das Programm beenden")
|
||||
assert not lauf.uebrig, lauf.uebrig
|
||||
assert not lauf.uebrig, lauf.diagnose()
|
||||
lauf.pruefen()
|
||||
|
||||
|
||||
@@ -396,7 +416,7 @@ def test_betrag_dialog_wenn_zelle_unsichtbar(lauf_mit_daten):
|
||||
(lambda: bool(app.ptree.get_children()), oeffnen, "Betrag ändern bei unsichtbarer Zelle"),
|
||||
(lambda: eingabe() is not None, tippen, "Betrag im Dialog eingeben"),
|
||||
])
|
||||
assert not lauf.uebrig, lauf.uebrig
|
||||
assert not lauf.uebrig, lauf.diagnose()
|
||||
assert any(p["betrag"] == 777 and p["manuell"] for p in app.positionen)
|
||||
del app.ptree.bbox
|
||||
lauf.pruefen()
|
||||
@@ -533,7 +553,7 @@ def test_windows_popup_kommt_nach_alt_tab_wieder_nach_vorn(lauf_mit_daten):
|
||||
fremd.geometry("400x300+50+50")
|
||||
fremd.update()
|
||||
m.update(besitzer=win32.besitzer_von(d), haupt=win32.hwnd(lauf.root),
|
||||
haupt_bedienbar=win32.ist_bedienbar(lauf.root))
|
||||
haupt_bedienbar=win32.ist_bedienbar(lauf.root), taskleiste=win32.hat_taskleisteneintrag(d))
|
||||
win32.nach_vorn(fremd) # „woanders hingeklickt“
|
||||
lauf.root.update()
|
||||
m["woanders"] = win32.stapel(d, lauf.root, fremd)
|
||||
@@ -548,34 +568,38 @@ def test_windows_popup_kommt_nach_alt_tab_wieder_nach_vorn(lauf_mit_daten):
|
||||
(lambda: lauf.dialog(InfoDialog) is not None, lambda: lauf.root.after(150, messen), "messen"),
|
||||
(lambda: "zurueck" in m and lauf.dialog(InfoDialog) is None, lambda: None, "geschlossen"),
|
||||
], sekunden=10)
|
||||
assert not lauf.uebrig, lauf.uebrig
|
||||
assert not lauf.uebrig, lauf.diagnose()
|
||||
assert m["besitzer"] == m["haupt"], "Popup gehört nicht dem Hauptfenster"
|
||||
assert m["haupt_bedienbar"] is False, "Hauptfenster muss gesperrt sein, solange das Popup offen ist"
|
||||
assert m["haupt_bedienbar"] is True, "Hauptfenster soll verschiebbar bleiben (nur der Inhalt ist gesperrt)"
|
||||
assert m["taskleiste"] is True, "Popup braucht einen eigenen Eintrag in der Taskleiste"
|
||||
assert m["woanders"][0] == 2, f"Testaufbau: das fremde Fenster sollte oben liegen ({m['woanders']})"
|
||||
assert m["zurueck"][:2] == [0, 1], f"Popup liegt nach dem Zurückholen nicht über dem Hauptfenster: {m['zurueck']}"
|
||||
assert win32.ist_bedienbar(lauf.root), "Hauptfenster nach dem Schließen nicht wieder freigegeben"
|
||||
lauf.pruefen()
|
||||
|
||||
|
||||
@nur_windows
|
||||
def test_windows_verschachtelte_rueckfrage(lauf_mit_daten):
|
||||
"""Händler-Dialog → Rückfrage: Rückfrage gehört dem Händler-Dialog; beim Schließen der Reihe nach frei."""
|
||||
from provtool.gui import win32
|
||||
def test_verschachtelte_rueckfrage_sperrt_der_reihe_nach(lauf_mit_daten):
|
||||
"""Händler-Dialog -> Rückfrage: gesperrt sind Hauptfenster-Inhalt und Händler-Dialog (nicht dessen
|
||||
Titelleiste); nach der Rückfrage ist der Händler-Dialog wieder frei, das Hauptfenster noch nicht."""
|
||||
from provtool.gui import modal, win32
|
||||
from provtool.gui import win95 as w
|
||||
from provtool.gui.dialogs import HaendlerDialog
|
||||
lauf = lauf_mit_daten
|
||||
m = {}
|
||||
rueckfrage = lambda: next((d for d in lauf.dialoge() if d.title() == "Test-Rückfrage"), None) # noqa: E731
|
||||
gesperrt = lambda wdg: modal.TAG in wdg.bindtags() # noqa: E731
|
||||
|
||||
def messen_innen():
|
||||
h, r = lauf.dialog(HaendlerDialog), rueckfrage()
|
||||
m.update(r_besitzer=win32.besitzer_von(r), h=win32.hwnd(h), h_an=win32.ist_bedienbar(h),
|
||||
haupt_an=win32.ist_bedienbar(lauf.root))
|
||||
m.update(h_inhalt=gesperrt(h.liste), h_titel=gesperrt(h.titelleiste) if h.titelleiste else False,
|
||||
haupt_inhalt=gesperrt(lauf.app.ptree), haupt_titel=gesperrt(lauf.app.rahmen.titelleiste)
|
||||
if lauf.app.rahmen.titelleiste else False,
|
||||
r_besitzer=win32.besitzer_von(r), h=win32.hwnd(h))
|
||||
r.destroy()
|
||||
|
||||
def messen_aussen():
|
||||
h = lauf.dialog(HaendlerDialog)
|
||||
m.update(h_an_danach=win32.ist_bedienbar(h), haupt_an_danach=win32.ist_bedienbar(lauf.root))
|
||||
m.update(h_inhalt_danach=gesperrt(h.liste), haupt_inhalt_danach=gesperrt(lauf.app.ptree))
|
||||
h.abbrechen()
|
||||
|
||||
lauf.ablauf([
|
||||
@@ -586,11 +610,13 @@ def test_windows_verschachtelte_rueckfrage(lauf_mit_daten):
|
||||
(lambda: "h" in m and rueckfrage() is None, messen_aussen, "außen messen"),
|
||||
(lambda: lauf.dialog(HaendlerDialog) is None, lambda: None, "alles zu"),
|
||||
], sekunden=12)
|
||||
assert not lauf.uebrig, lauf.uebrig
|
||||
assert m["r_besitzer"] == m["h"], "Rückfrage gehört nicht dem Händler-Dialog"
|
||||
assert m["h_an"] is False and m["haupt_an"] is False
|
||||
assert m["h_an_danach"] is True and m["haupt_an_danach"] is False
|
||||
assert win32.ist_bedienbar(lauf.root)
|
||||
assert not lauf.uebrig, lauf.diagnose()
|
||||
assert m["h_inhalt"] and m["haupt_inhalt"], "Inhalte müssen gesperrt sein, solange die Rückfrage offen ist"
|
||||
assert not m["h_titel"] and not m["haupt_titel"], "Titelleisten (verschieben) dürfen nicht gesperrt sein"
|
||||
assert not m["h_inhalt_danach"] and m["haupt_inhalt_danach"]
|
||||
assert not gesperrt(lauf.app.ptree), "Hauptfenster nach dem Schließen nicht wieder freigegeben"
|
||||
if sys.platform.startswith("win"):
|
||||
assert m["r_besitzer"] == m["h"], "Rückfrage gehört nicht dem Händler-Dialog"
|
||||
lauf.pruefen()
|
||||
|
||||
|
||||
@@ -612,8 +638,240 @@ def test_windows_rundgang_sperrt_und_gibt_frei(lauf_mit_daten):
|
||||
messen_und_weiter, f"Schritt {i + 1}"))
|
||||
schritte.append((IMMER, lambda: rg().beenden(), "Rundgang beenden"))
|
||||
lauf.ablauf(schritte, sekunden=12)
|
||||
assert not lauf.uebrig, lauf.uebrig
|
||||
assert not lauf.uebrig, lauf.diagnose()
|
||||
assert all(m["gesperrt"]), "Hauptfenster während des Rundgangs nicht gesperrt"
|
||||
assert all(m["besitzer"]), "Sprechblase gehört nicht dem Hauptfenster"
|
||||
assert win32.ist_bedienbar(lauf.root), "Hauptfenster nach dem Rundgang nicht freigegeben"
|
||||
lauf.pruefen()
|
||||
|
||||
|
||||
# =========================================================================== Rückmeldungen vom 2.11. (Teil 2)
|
||||
|
||||
def test_gedrueckte_knoepfe_behalten_ihre_schrift(lauf_mit_daten):
|
||||
"""Gemeldet: Im gedrückten Zustand war die Beschriftung weg (activeforeground = Grau)."""
|
||||
from provtool.gui import win95 as w
|
||||
lauf = lauf_mit_daten
|
||||
for b in (w.knopf(lauf.root, "Test"), tk.Button(lauf.root, text="roh")):
|
||||
assert b.cget("activeforeground") != b.cget("activebackground"), "Schrift gedrückter Knöpfe unsichtbar"
|
||||
b.destroy()
|
||||
lauf.pruefen()
|
||||
|
||||
|
||||
def test_tipp_text_bleibt_im_sichtbaren_bereich(lauf_mit_daten):
|
||||
from provtool.gui.assistent import TIPPS, TippDesTages
|
||||
lauf = lauf_mit_daten
|
||||
m = {}
|
||||
|
||||
def messen():
|
||||
d = lauf.dialog(TippDesTages)
|
||||
rahmen = d.text.master
|
||||
for t in TIPPS: # jeden Tipp einmal anzeigen
|
||||
d.text.configure(text=t)
|
||||
d.update_idletasks()
|
||||
m.setdefault("breiten", []).append((d.text.winfo_reqwidth(), rahmen.winfo_width()))
|
||||
m.setdefault("hoehen", []).append((d.text.winfo_reqheight(), rahmen.winfo_height()))
|
||||
d.abbrechen()
|
||||
|
||||
lauf.ablauf([
|
||||
(IMMER, lauf.app.tipp_des_tages, "Tipp öffnen"),
|
||||
(lambda: lauf.dialog(TippDesTages) is not None, lambda: lauf.root.after(100, messen), "messen"),
|
||||
(lambda: "breiten" in m and lauf.dialog(TippDesTages) is None, lambda: None, "zu"),
|
||||
])
|
||||
assert not lauf.uebrig, lauf.diagnose()
|
||||
for text_b, rahmen_b in m["breiten"]:
|
||||
assert text_b <= rahmen_b, f"Tipp-Text ({text_b}px) breiter als sein Bereich ({rahmen_b}px)"
|
||||
for text_h, rahmen_h in m["hoehen"]:
|
||||
assert text_h <= rahmen_h, f"Tipp-Text ({text_h}px) höher als sein Bereich ({rahmen_h}px)"
|
||||
lauf.pruefen()
|
||||
|
||||
|
||||
def test_strg_ruecktaste_loescht_ganzes_wort(lauf_mit_daten):
|
||||
from provtool.gui import win95 as w
|
||||
lauf = lauf_mit_daten
|
||||
e = tk.Entry(lauf.root)
|
||||
e.insert(0, "Mobilfunk Schmid GmbH")
|
||||
ev = type("E", (), {"widget": e})()
|
||||
e.icursor("end")
|
||||
w._wort_weg(ev, -1)
|
||||
assert e.get() == "Mobilfunk Schmid "
|
||||
w._wort_weg(ev, -1)
|
||||
assert e.get() == "Mobilfunk "
|
||||
e.icursor(0)
|
||||
w._wort_weg(ev, 1)
|
||||
assert e.get() == ""
|
||||
# Bindung ist für alle Eingabefelder aktiv
|
||||
for klasse in ("Entry", "TEntry", "TCombobox"):
|
||||
assert lauf.root.bind_class(klasse, "<Control-BackSpace>"), klasse
|
||||
assert lauf.root.bind_class(klasse, "<Control-Delete>"), klasse
|
||||
e.destroy()
|
||||
lauf.pruefen()
|
||||
|
||||
|
||||
def test_menue_wechselt_beim_ueberfahren(lauf_mit_daten):
|
||||
"""Gemeldet: Bei offenem Menü wechselte es nicht mit, wenn man zum nächsten Eintrag fuhr."""
|
||||
lauf = lauf_mit_daten
|
||||
leiste = lauf.app.menueleiste
|
||||
datei, haendler = leiste.knoepfe["Datei"], leiste.knoepfe["Händler"]
|
||||
m = {}
|
||||
|
||||
def ueberfahren():
|
||||
popup = leiste.menues[datei]
|
||||
ev = type("E", (), {"x_root": haendler.winfo_rootx() + 3, "y_root": haendler.winfo_rooty() + 3})()
|
||||
popup._bewegung(ev)
|
||||
|
||||
def pruefen_und_esc():
|
||||
m["offen"] = leiste.offener_knopf
|
||||
m["popup_offen"] = leiste.menues[haendler].offen
|
||||
leiste.menues[haendler].fenster.event_generate("<Escape>")
|
||||
leiste.menues[haendler].schliessen()
|
||||
|
||||
lauf.ablauf([
|
||||
(IMMER, lambda: leiste._klick(datei), "Datei öffnen"),
|
||||
(lambda: leiste.menues[datei].offen, ueberfahren, "zu „Händler“ fahren"),
|
||||
(lambda: leiste.menues[haendler].offen, pruefen_und_esc, "prüfen + schließen"),
|
||||
(lambda: leiste.offener_knopf is None, lambda: None, "alles zu"),
|
||||
])
|
||||
assert not lauf.uebrig, lauf.diagnose()
|
||||
assert m["offen"] is haendler and m["popup_offen"]
|
||||
assert not leiste.menues[datei].offen
|
||||
lauf.pruefen()
|
||||
|
||||
|
||||
def test_menue_geht_unter_seinem_menuepunkt_auf(lauf_mit_daten):
|
||||
"""Unter Windows landete das Menü zunächst oben links in der Bildschirmecke."""
|
||||
lauf = lauf_mit_daten
|
||||
leiste = lauf.app.menueleiste
|
||||
m = {}
|
||||
for name in ("Datei", "Händler"):
|
||||
knopf = leiste.knoepfe[name]
|
||||
|
||||
def messen(knopf=knopf, name=name):
|
||||
f = leiste.menues[knopf].fenster
|
||||
m[name] = (f.winfo_rootx() - knopf.winfo_rootx(),
|
||||
f.winfo_rooty() - (knopf.winfo_rooty() + knopf.winfo_height()))
|
||||
leiste.schliessen()
|
||||
lauf.ablauf([(IMMER, lambda knopf=knopf: leiste._klick(knopf), f"{name} öffnen"),
|
||||
(lambda knopf=knopf: leiste.menues[knopf].offen, lambda: lauf.root.after(100, messen), "messen"),
|
||||
(lambda name=name: name in m, lambda: None, "fertig")])
|
||||
assert not lauf.uebrig, lauf.diagnose()
|
||||
for name, (dx, dy) in m.items():
|
||||
assert abs(dx) <= 3 and abs(dy) <= 3, f"Menü „{name}“ nicht unter seinem Menüpunkt (Abstand {dx}, {dy})"
|
||||
lauf.pruefen()
|
||||
|
||||
|
||||
def test_menue_befehl_wird_ausgefuehrt(lauf_mit_daten):
|
||||
from provtool.gui.assistent import TippDesTages
|
||||
lauf = lauf_mit_daten
|
||||
leiste = lauf.app.menueleiste
|
||||
hilfe = leiste.knoepfe["?"]
|
||||
|
||||
def tipp_waehlen():
|
||||
popup = leiste.menues[hilfe]
|
||||
i = next(i for i, (e, _, _) in enumerate(popup.zeilen) if e["label"].startswith("Tipp des Tages"))
|
||||
popup._ausfuehren(i)
|
||||
|
||||
lauf.ablauf([
|
||||
(IMMER, lambda: leiste._klick(hilfe), "? öffnen"),
|
||||
(lambda: leiste.menues[hilfe].offen, tipp_waehlen, "Tipp des Tages wählen"),
|
||||
(lambda: lauf.dialog(TippDesTages) is not None, lambda: lauf.dialog(TippDesTages).abbrechen(), "zu"),
|
||||
])
|
||||
assert not lauf.uebrig, lauf.diagnose()
|
||||
assert not leiste.menues[hilfe].offen
|
||||
lauf.pruefen()
|
||||
|
||||
|
||||
def test_hauptfenster_bei_offenem_dialog_verschiebbar_inhalt_gesperrt(lauf_mit_daten, monkeypatch):
|
||||
"""Gemeldet: Bei offenem Dialog ließ sich das Hauptfenster nicht verschieben."""
|
||||
from provtool.gui import modal, rahmen
|
||||
from provtool.gui.dialogs import InfoDialog
|
||||
monkeypatch.setattr(rahmen, "NATIV_VERSCHIEBEN", False) # Tk-Weg prüfen (nativ macht Windows selbst)
|
||||
lauf = lauf_mit_daten
|
||||
app = lauf.app
|
||||
if not app.rahmen.klassisch:
|
||||
pytest.skip("nur im Win95-Rahmen")
|
||||
m = {"neu_aufgerufen": False}
|
||||
monkeypatch.setattr(type(app), "neu", lambda self: m.__setitem__("neu_aufgerufen", True))
|
||||
titel = app.rahmen.titelleiste.titel_lbl
|
||||
|
||||
def pruefen():
|
||||
x0 = lauf.root.winfo_x()
|
||||
rx, ry = titel.winfo_rootx() + 30, titel.winfo_rooty() + 5
|
||||
titel.event_generate("<ButtonPress-1>", x=30, y=5, rootx=rx, rooty=ry)
|
||||
titel.event_generate("<B1-Motion>", x=70, y=5, rootx=rx + 40, rooty=ry)
|
||||
titel.event_generate("<ButtonRelease-1>", x=70, y=5, rootx=rx + 40, rooty=ry)
|
||||
lauf.root.update()
|
||||
m["verschoben"] = lauf.root.winfo_x() - x0
|
||||
knopf = app.tb["Neu"] # Klick auf den gesperrten Inhalt
|
||||
knopf.event_generate("<ButtonPress-1>", x=5, y=5)
|
||||
knopf.event_generate("<ButtonRelease-1>", x=5, y=5)
|
||||
m["gesperrt"] = modal.TAG in app.ptree.bindtags()
|
||||
lauf.dialog(InfoDialog).abbrechen()
|
||||
|
||||
lauf.ablauf([
|
||||
(IMMER, lambda: InfoDialog(lauf.root).zeigen(), "Dialog öffnen"),
|
||||
(lambda: lauf.dialog(InfoDialog) is not None, lambda: lauf.root.after(100, pruefen), "prüfen"),
|
||||
(lambda: "verschoben" in m and lauf.dialog(InfoDialog) is None, lambda: None, "zu"),
|
||||
])
|
||||
assert not lauf.uebrig, f"{lauf.uebrig} {m}\n" + "\n".join(lauf.fehler)
|
||||
assert m["verschoben"] == 40, f"Hauptfenster ließ sich nicht verschieben ({m['verschoben']} px)"
|
||||
assert m["gesperrt"] and not m["neu_aufgerufen"], "Inhalt des Hauptfensters war nicht gesperrt"
|
||||
assert modal.TAG not in app.ptree.bindtags(), "Sperre nach dem Schließen nicht aufgehoben"
|
||||
lauf.pruefen()
|
||||
|
||||
|
||||
def test_rand_zeiger_wird_zurueckgesetzt(lauf_mit_daten):
|
||||
"""Gemeldet: Der Größenänderungs-Zeiger blieb manchmal stehen."""
|
||||
lauf = lauf_mit_daten
|
||||
r = lauf.app.rahmen
|
||||
if not r.klassisch:
|
||||
pytest.skip("nur im Win95-Rahmen")
|
||||
ev = type("E", (), {"x": 2, "y": lauf.root.winfo_height() // 2})()
|
||||
r._rand_cursor(ev)
|
||||
assert r.aussen.cget("cursor"), "am Rand muss der Größenänderungs-Zeiger erscheinen"
|
||||
r.inhalt.event_generate("<Enter>")
|
||||
lauf.root.update()
|
||||
assert r.aussen.cget("cursor") == "", "Zeiger wurde beim Betreten des Inhalts nicht zurückgesetzt"
|
||||
# Ecken: in der Nähe des Ecks diagonal
|
||||
assert r._welcher_rand(2, 10) == "nw" and r._welcher_rand(r.aussen.winfo_width() - 3, 10) == "ne"
|
||||
lauf.pruefen()
|
||||
|
||||
|
||||
def test_eigene_kennungen_ausblenden_in_der_oberflaeche(lauf_mit_daten):
|
||||
from provtool.db import EIGEN
|
||||
lauf = lauf_mit_daten
|
||||
app = lauf.app
|
||||
alle_vorher = int(app.htree.item("-1", "values")[0])
|
||||
app.db.eigene_setzen("freenet", "999")
|
||||
app._aktualisieren()
|
||||
assert app.htree.exists(str(EIGEN)), "Eintrag „(Eigene – ausgeblendet)“ fehlt"
|
||||
assert int(app.htree.item("-1", "values")[0]) == alle_vorher - 1, "eigene Positionen zählen noch mit"
|
||||
assert all(p["haendler_id"] != EIGEN for p in app._gefiltert())
|
||||
lauf.pruefen()
|
||||
|
||||
|
||||
@nur_windows
|
||||
def test_windows_minimieren_mit_offenem_dialog(lauf_mit_daten):
|
||||
"""Minimieren bei offenem Dialog darf den Dialog nicht zerstören; nach dem Wiederherstellen ist er da."""
|
||||
from provtool.gui import win32
|
||||
from provtool.gui.dialogs import InfoDialog
|
||||
lauf = lauf_mit_daten
|
||||
m = {}
|
||||
|
||||
def minimieren():
|
||||
lauf.app.rahmen.minimieren()
|
||||
lauf.root.update()
|
||||
m["minimiert"] = win32.ist_minimiert(lauf.root)
|
||||
win32.user32().ShowWindow(win32.hwnd(lauf.root), 9) # SW_RESTORE (wie Klick in der Taskleiste)
|
||||
lauf.root.update()
|
||||
m["dialog_da"] = lauf.dialog(InfoDialog) is not None
|
||||
lauf.dialog(InfoDialog).abbrechen()
|
||||
|
||||
lauf.ablauf([
|
||||
(IMMER, lambda: InfoDialog(lauf.root).zeigen(), "Dialog öffnen"),
|
||||
(lambda: lauf.dialog(InfoDialog) is not None, lambda: lauf.root.after(150, minimieren), "minimieren"),
|
||||
(lambda: "dialog_da" in m, lambda: None, "fertig"),
|
||||
], sekunden=12)
|
||||
assert not lauf.uebrig, lauf.diagnose()
|
||||
assert m["minimiert"], "Hauptfenster wurde nicht minimiert"
|
||||
assert m["dialog_da"], "Dialog nach dem Minimieren verschwunden"
|
||||
lauf.pruefen()
|
||||
Reference in new issue
Block a user