PyQt6 Bauplan Fenster

Teil 2 – Grundlagen: resize(), setMinimumSize(), setMaximumSize(), move(), frameGeometry(), availableGeometry()

Quadratische Gleichung als nutzbare Anwendung

Zurück

Diese Webseite stellt für den Quellcode Download- und Kopierfunktionen zur Verfügung. Das geht nur mit JavaScript. Wenn du mich für einen unsicheren Kantonisten hältst, verlasse diese Webseite. Alle Informationen und Angebote sind ohne Gewähr!


Python Code
#!/usr/bin/env python3 import sys import math import os from PyQt6.QtWidgets import ( QApplication, QWidget, QLabel, QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout, ) from PyQt6.QtGui import QIcon # Verzeichnis dieser Datei, damit das Icon unabhängig vom Startort gefunden wird BASE_DIR = os.path.dirname(os.path.abspath(__file__)) ICON_PATH = os.path.join(BASE_DIR, "icon.png") class QuadraticSolver(QWidget): def __init__(self): super().__init__() self.setWindowTitle("Quadratische Gleichung") # --- Icon --- if os.path.exists(ICON_PATH): self.setWindowIcon(QIcon(ICON_PATH)) # --- Feste Startgröße --- self.resize(420, 200) # --- Größenbeschränkungen --- # Mindestgröße: darunter würden Eingabefelder und Button zu eng werden self.setMinimumSize(360, 160) # Maximalgröße: das Fenster soll nicht beliebig aufreißbar sein, # da ein reines Eingabeformular bei zu großer Fläche unproportioniert wirkt self.setMaximumSize(700, 350) # --- Eingabefelder für a, b, c --- self.input_a = QLineEdit() self.input_a.setPlaceholderText("a") self.input_b = QLineEdit() self.input_b.setPlaceholderText("b") self.input_c = QLineEdit() self.input_c.setPlaceholderText("c") # Zeile mit den drei Eingabefeldern nebeneinander, # dazwischen kleine Labels zur Lesbarkeit der Formel input_row = QHBoxLayout() input_row.addWidget(self.input_a) input_row.addWidget(QLabel("x² +")) input_row.addWidget(self.input_b) input_row.addWidget(QLabel("x +")) input_row.addWidget(self.input_c) input_row.addWidget(QLabel("= 0")) # --- Button --- self.button_calc = QPushButton("Berechnen") self.button_calc.clicked.connect(self.calculate) # --- Ergebnis-Anzeige --- self.result_label = QLabel("") # --- Gesamtlayout (senkrecht gestapelt) --- main_layout = QVBoxLayout() main_layout.addLayout(input_row) main_layout.addWidget(self.button_calc) main_layout.addWidget(self.result_label) self.setLayout(main_layout) # Fenster mittig auf dem Bildschirm positionieren self.center_on_screen() def center_on_screen(self): """Positioniert das Fenster mittig auf dem primären Bildschirm.""" screen = QApplication.primaryScreen() if screen is None: return screen_geometry = screen.availableGeometry() window_geometry = self.frameGeometry() center_point = screen_geometry.center() window_geometry.moveCenter(center_point) # move() erwartet die obere linke Ecke, daher aus window_geometry entnehmen self.move(window_geometry.topLeft()) def calculate(self): """Liest a, b, c aus, prüft die Eingabe und berechnet die Nullstellen.""" try: a = float(self.input_a.text().replace(",", ".")) b = float(self.input_b.text().replace(",", ".")) c = float(self.input_c.text().replace(",", ".")) except ValueError: self.result_label.setText("Bitte gültige Zahlen für a, b und c eingeben.") return if a == 0: self.result_label.setText("a darf nicht 0 sein (sonst keine quadratische Gleichung).") return diskriminante = b**2 - 4 * a * c if diskriminante > 0: x1 = (-b + math.sqrt(diskriminante)) / (2 * a) x2 = (-b - math.sqrt(diskriminante)) / (2 * a) self.result_label.setText(f"Zwei Lösungen: x1 = {x1:.4g}, x2 = {x2:.4g}") elif diskriminante == 0: x = -b / (2 * a) self.result_label.setText(f"Eine Lösung: x = {x:.4g}") else: realteil = -b / (2 * a) imagteil = math.sqrt(-diskriminante) / (2 * a) self.result_label.setText( f"Keine reelle Lösung: x1 = {realteil:.4g} + {imagteil:.4g}i, " f"x2 = {realteil:.4g} - {imagteil:.4g}i" ) def main(): app = QApplication(sys.argv) window = QuadraticSolver() window.show() sys.exit(app.exec()) if __name__ == "__main__": main()


Fenster-Icon:
QIcon(ICON_PATH) [Zeile 27] lädt die PNG-Datei, setWindowIcon() [Zeile 28] setzt sie als Icon in Titelleiste und Taskleiste. Wichtig: Ich löse den Pfad relativ zum Skript-Verzeichnis auf (os.path.dirname(os.path.abspath(__file__))) [Zeile 18], damit das Icon auch gefunden wird, wenn du das Programm von einem anderen Arbeitsverzeichnis aus startest. Die icon.png muss dafür im selben Ordner wie das Python-Skript liegen.

Feste Startgröße:
self.resize(420, 200) [Zeile 31] setzt die initiale Fenstergröße. Das ist unabhängig von Minimum/Maximum – es ist einfach der Startwert, den der Nutzer danach frei verändern kann (innerhalb der Grenzen).

Mindest- und Maximalgröße
setMinimumSize() und setMaximumSize() [Zeile 35/38] verhindern, dass der Nutzer das Fenster so klein zieht, dass Eingabefelder überlappen, oder so groß, dass ein simples Formular unnatürlich gestreckt wirkt. Qt respektiert diese Grenzen automatisch beim Ziehen am Fensterrand – dafür ist kein zusätzlicher Event-Handler nötig.

Zentrierung auf dem Bildschirm. [Zeile 78-90] Das ist der interessanteste Teil:
QApplication.primaryScreen() liefert den Hauptbildschirm. screen.availableGeometry() gibt die nutzbare Fläche zurück (ohne Taskleiste/Dock). self.frameGeometry() liefert die Geometrie des Fensters inklusive Rahmen/Titelleiste – wichtig, weil sonst die Zentrierung leicht schief ist. window_geometry.moveCenter(screen_geometry.center()) verschiebt dieses Geometrie-Rechteck so, dass sein Mittelpunkt auf dem Bildschirmmittelpunkt liegt. self.move(window_geometry.topLeft()) setzt die tatsächliche Fensterposition anhand der oberen linken Ecke – move() erwartet nämlich diesen Punkt, nicht den Mittelpunkt.

Ich habe das Ganze in eine eigene Methode center_on_screen() ausgelagert, statt es direkt in __init__ zu schreiben – das hält den Konstruktor übersichtlich und macht die Methode wiederverwendbar (z. B. später per Menüpunkt "Fenster zentrieren", falls gewünscht).


Zurück