From adbb035cf114282ffe15a6ce7d2087dc3ae433b3 Mon Sep 17 00:00:00 2001 From: TheMockTv Date: Mon, 7 Sep 2026 00:41:35 +0200 Subject: [PATCH] Pruefstaende auf den zweiten Monitor, Desktop-Verknuepfung mit Symbol Seine Ansagen "teste links auf dem 1080p monitor nicht mehr auf dem main ... weil da schau ich nun video" "und das steuertool hat noch kein installer und die rechnungstool hat das icon nicht auf dem desktop etc selbe beim steuertool" Pruefplatz Der Platz fuer Pruefstandsfenster lag bei "Bildschirmbreite + 20", also RECHTS neben dem Hauptmonitor. Bei ihm steht der zweite Monitor aber LINKS (x = -1920), und rechts ist gar nichts: die Fenster gingen ins Leere. Sie liefen, waren aber nirgends zu sehen - das hat beim Bildermachen einige Zeit gekostet, ehe es auffiel. theme.pruefplatz() sucht jetzt den nicht-primaeren Monitor und liefert dessen Ecke. Gibt es keinen, bleibt es beim alten Verhalten. Das Steuerrechnungstool hatte ueberhaupt keine Sonderposition - dessen Pruefstandsfenster gingen mitten auf den Hauptbildschirm auf. Verknuepfungen Der Haken "Verknuepfung auf dem Desktop" ist jetzt vorgesetzt statt abgewaehlt, und jede Verknuepfung traegt IconFilename ausdruecklich. Ohne das erbt sie ihr Symbol vom UPDATER - und Windows zeigte an ihrer Stelle das nackte Standardsymbol. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax --- Installer.iss | 11 +++++++--- app.py | 3 ++- theme.py | 61 ++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 68 insertions(+), 7 deletions(-) diff --git a/Installer.iss b/Installer.iss index 86f6ce7..f4e7025 100644 --- a/Installer.iss +++ b/Installer.iss @@ -68,8 +68,11 @@ AppComments=Erprobungsfassung. Benutzung auf eigene Gefahr. Name: "deutsch"; MessagesFile: "compiler:Languages\German.isl" [Tasks] +; Kein "unchecked": der Haken ist vorgesetzt. Er hatte nach dem +; Installieren kein Symbol auf dem Desktop und musste das Programm +; suchen (07.09.2026). Wer es nicht will, nimmt den Haken heraus. Name: "desktopicon"; Description: "Verknüpfung auf dem Desktop anlegen"; \ - GroupDescription: "Zusätzliche Verknüpfungen:"; Flags: unchecked + GroupDescription: "Zusätzliche Verknüpfungen:" [Files] ; Der Updater - das ist, was der Benutzer startet. @@ -80,9 +83,11 @@ Source: "dist\{#ExeProgramm}"; DestDir: "{app}"; Flags: ignoreversion [Icons] ; Beide Verknuepfungen zeigen auf den UPDATER, nicht auf das Programm. -Name: "{group}\{#Name}"; Filename: "{app}\{#ExeUpdater}" +; IconFilename ausdruecklich: ohne das erbt die Verknuepfung das Symbol vom +; UPDATER, und Windows zeigte an ihrer Stelle das nackte Standardsymbol. +Name: "{group}\{#Name}"; Filename: "{app}\{#ExeUpdater}"; IconFilename: "{app}\{#ExeProgramm}" Name: "{group}\{#Name} deinstallieren"; Filename: "{uninstallexe}" -Name: "{userdesktop}\{#Name}"; Filename: "{app}\{#ExeUpdater}"; Tasks: desktopicon +Name: "{userdesktop}\{#Name}"; Filename: "{app}\{#ExeUpdater}"; IconFilename: "{app}\{#ExeProgramm}"; Tasks: desktopicon [Run] Filename: "{app}\{#ExeUpdater}"; Description: "{#Name} jetzt starten"; \ diff --git a/app.py b/app.py index b2f9dcf..e2c9186 100644 --- a/app.py +++ b/app.py @@ -89,7 +89,8 @@ class RechnungsApp(ThemeMixin, MeldungMixin, KorrekturMixin, EinstellungenMixin, # dem zweiten Monitor, wenn einer da ist) - sichtbar, aber nicht im # Weg. Unsichtbar machen waere falsch: dann sieht niemand mehr, was # der Pruefstand eigentlich tut. - self.geometry(f"+{self.winfo_screenwidth() + 20}+40") + self.geometry(theme.pruefplatz() + or f"+{self.winfo_screenwidth() + 20}+40") try: # Kein Eintrag in der Taskleiste: das Fenster liegt neben # dem Bildschirm, und ein Eintrag, den man anklickt, ohne diff --git a/theme.py b/theme.py index 6da642c..25502ef 100644 --- a/theme.py +++ b/theme.py @@ -66,6 +66,61 @@ def titelleiste_faerben(fenster, dunkel): return False +def pruefplatz(): + """Wo ein Pruefstand seine Fenster aufmachen soll: "+x+y" oder "". + + Seine Ansage am 07.09.2026: *"teste links auf dem 1080p monitor nicht mehr + auf dem main ... weil da schau ich nun video"*. + + Vorher lag der Platz bei `Bildschirmbreite + 20` - also RECHTS neben dem + Hauptmonitor. Bei ihm steht der zweite Monitor aber LINKS (x = -1920), und + rechts ist gar nichts: die Fenster gingen ins Leere. Sie liefen zwar, waren + aber nirgends zu sehen - das hat beim Bildermachen einige Zeit gekostet. + + Gesucht wird deshalb der nicht-primaere Monitor. Gibt es keinen, bleibt es + beim alten Verhalten (neben den Bildschirm), denn im Weg sein soll ein + Pruefstand auch dann nicht. + """ + if not sys.platform.startswith("win"): + return "" + try: + import ctypes + from ctypes import wintypes + + class RECT(ctypes.Structure): + _fields_ = [("left", ctypes.c_long), ("top", ctypes.c_long), + ("right", ctypes.c_long), ("bottom", ctypes.c_long)] + + class MONITORINFO(ctypes.Structure): + _fields_ = [("cbSize", wintypes.DWORD), ("rcMonitor", RECT), + ("rcWork", RECT), ("dwFlags", wintypes.DWORD)] + + gefunden = [] + + def je_monitor(hmon, hdc, lprect, daten): + info = MONITORINFO() + info.cbSize = ctypes.sizeof(MONITORINFO) + if ctypes.windll.user32.GetMonitorInfoW(hmon, ctypes.byref(info)): + r = info.rcWork + gefunden.append((bool(info.dwFlags & 1), # 1 = MONITORINFOF_PRIMARY + r.left, r.top, r.right - r.left)) + return 1 + + RUECKRUF = ctypes.WINFUNCTYPE(ctypes.c_int, wintypes.HMONITOR, + wintypes.HDC, ctypes.POINTER(RECT), + wintypes.LPARAM) + ctypes.windll.user32.EnumDisplayMonitors(0, 0, RUECKRUF(je_monitor), 0) + # Der breiteste Nebenmonitor - bei mehreren der linkeste. + neben = sorted((m for m in gefunden if not m[0]), + key=lambda m: (-m[3], m[1])) + if neben: + _, x, y, _ = neben[0] + return f"+{x + 30}+{y + 40}" + except Exception: # noqa: BLE001 - dann eben der alte Weg + pass + return "" + + def testlauf(): """Faehrt gerade ein Pruefstand das Programm? @@ -478,10 +533,10 @@ class ThemeMixin: """ d.configure(bg=self.col_bg) if testlauf(): - # Wie das Hauptfenster: neben den Bildschirm, und ohne grab_set - + # Wie das Hauptfenster: auf den zweiten Monitor, und ohne grab_set - # ein Dialog, der Maus und Tastatur festhaelt, blockiert den - # Menschen, der nebenher schreibt. - d.geometry(f"+{d.winfo_screenwidth() + 20}+40") + # Menschen, der nebenher arbeitet. + d.geometry(pruefplatz() or f"+{d.winfo_screenwidth() + 20}+40") d.grab_set = lambda *a, **k: None try: d.attributes("-toolwindow", True) # nicht in die Taskleiste