Pruefstaende auf den zweiten Monitor, Desktop-Verknuepfung mit Symbol
Seine Ansage: "teste links auf dem 1080p monitor nicht mehr auf dem main ... weil da schau ich nun video" - und danach "das nun der richtige das fuer beide". Dieses Programm hatte ueberhaupt keine Sonderposition fuer den Testlauf: seine Pruefstandsfenster gingen mitten auf den Hauptbildschirm auf, waehrend jemand daran arbeitete. Jetzt auf dem zweiten Monitor und ohne Eintrag in der Taskleiste, wie im Rechnungstool. Der Platz kommt aus theme.pruefplatz() - dieselbe Datei in beiden Programmen. Dazu im Installer: der Haken "Verknuepfung auf dem Desktop" ist vorgesetzt statt abgewaehlt, und jede Verknuepfung traegt IconFilename ausdruecklich. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax
This commit is contained in:
parent
9d7aa1eec7
commit
f57c7f52f4
3 changed files with 82 additions and 6 deletions
|
|
@ -66,8 +66,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.
|
||||
|
|
@ -78,9 +81,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"; \
|
||||
|
|
|
|||
16
app.py
16
app.py
|
|
@ -86,6 +86,22 @@ class App(theme.ThemeMixin, tk.Tk):
|
|||
self._fenstersymbol()
|
||||
self.geometry("1000x680")
|
||||
self.minsize(820, 520)
|
||||
if TESTLAUF:
|
||||
# Ein Pruefstand bedient das Programm, waehrend nebenan jemand
|
||||
# arbeitet. Das Fenster geht deshalb auf dem ZWEITEN Monitor auf -
|
||||
# sichtbar, aber nicht im Weg. Seine Ansage am 07.09.2026: "teste
|
||||
# links auf dem 1080p monitor nicht mehr auf dem main". Bisher
|
||||
# ging es hier mitten auf den Hauptbildschirm.
|
||||
platz = theme.pruefplatz()
|
||||
if platz:
|
||||
self.geometry(platz)
|
||||
try:
|
||||
# Kein Eintrag in der Taskleiste: ein Eintrag, den man
|
||||
# anklickt, ohne dass etwas erscheint, ist schlimmer als
|
||||
# gar keiner.
|
||||
self.attributes("-toolwindow", True)
|
||||
except tk.TclError:
|
||||
pass
|
||||
|
||||
self.journal = db.Journal(JOURNAL)
|
||||
# Die Einstellungen des Programms liegen in der Journal-Tabelle, nicht
|
||||
|
|
|
|||
61
theme.py
61
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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue