DGHK Ostercamp 2024 : Python
„Fenster, Knöpfe, Schieberegler und Grafikeffekte unter Python“
1. Python Crashkurs Beispiele
1.1 Variablen
anzahl_kekse = 123 preis_pro_keks = 1.20 kosten = anzahl_kekse * preis_pro_keks print(kosten) # => 147.6
1.2 Listen
sachen = ["buch", "brille", "kekse"]
print(sachen)
# => ['buch', 'brille', 'kekse']
erste_sache = sachen[0]
print(erste_sache)
# => buch
dritte_sache = sachen[2]
print(dritte_sache)
# => kekse
vierte_sache = sachen[3]
print(vierte_sache)
# => IndexError: list index out of range
sachen.append("saft")
vierte_sache = sachen[3]
print(vierte_sache)
# => saft
1.3 Dictionaries
person = { "name": "Maria",
"alter": 15,
"hobbies": ["Lesen", "Programmieren", "Tischtennis"] }
print(person)
# => {'name': 'Maria', 'alter': 15, 'hobbies': ['Lesen', 'Programmieren', 'Tischtennis']}
name = person["name"]
print(name)
# => Maria
alter = person["alter"]
print(alter)
# => 15
hobbies = person["hobbies"]
print(hobbies)
# => ['Lesen', 'Programmieren', 'Tischtennis']
person["wohnort"] = "Berlin"
wohnort = person["wohnort"]
print(wohnort)
# => Berlin
1.4 Funktionen
def addiere(a, b):
return a + b
c = addiere(3, 4)
print(c)
# => 7
1.5 for-Schleifen
for zaehler in range(10):
print(zaehler)
# => zählt von 0 bis 9
obst = ["äpfel", "birnen", "bananen"]
for element in obst:
print("ich mag", element)
# => ich mag äpfel
# => ich mag birnen
# => ich mag bananen
1.6 while-Schleifen
while(True):
print("Bitte gib etwas ein! Beenden mit 'ENDE'")
eingabe = input()
# Die Eingabe wird mit "ENDE" verglichen:
if eingabe == "ENDE":
# Wenn der Vergleich wahr ist, verlassen wir die Schleife:
break
print("Du hast", eingabe, "eingegeben!")
print("Das Programm ist vorbei")
1.7 Module
import random as rand z1 = rand.random() print(z1) # => Zufallszahl zwischen 0 und 1 z2 = rand.randrange(10, 20) print(z2) # => Zufallszahl zwischen 10 und 19
2. PySimpleGUI Beispiele
2.1 Das Minimalbeispiel
import PySimpleGUI as sg
sg.set_options(font=("Courier", 30))
layout = [
[sg.Input(key="-EINGABE-")],
[sg.Button("Übertragen", key="-UEBERTRAGEN-")],
[sg.Input(key="-AUSGABE-", disabled=True)],
[sg.Button("Beenden", key="-BEENDEN-")]
]
window = sg.Window("Minimalbeispiel",
layout,
size=(300, 250))
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == "-BEENDEN-":
break
if event == "-UEBERTRAGEN-":
text_eingabe = values["-EINGABE-"]
window["-AUSGABE-"].update(text_eingabe)
window.close()
2.2 Das Minimalbeispiel, kommentiert
# Import des PySimpleGUI-Moduls unter dem Kürzel sg
import PySimpleGUI as sg
# Wir setzten die Option 'font' auf ("Courier", 30),
# damit die Schrift nicht so winzig ist!
sg.set_options(font=("Courier", 30))
# Das Layout ist eine zweidimensiopnale Tabelle!
# Jede Zeile der Tabelle ist eine Zeile im Layout!
# Das Schlüsselwortargument "key" legt den Namen des Elementes fest.
layout = [
# Das Eingabefeld
[sg.Input(key="-EINGABE-")],
# Der Button "Übertragen"
[sg.Button("Übertragen", key="-UEBERTRAGEN-")],
# Das Ausgabefeld
[sg.Input(key="-AUSGABE-", disabled=True)],
# Der Button "Beenden"
[sg.Button("Beenden", key="-BEENDEN-")]
]
# Hier erzeugen wir das Hauptfenster.
# Das zweite Argument ist immer das layout!
window = sg.Window("Minimalbeispiel",
layout,
size=(300, 250))
# Die Hauptschleife unseres Programms:
while True:
# window.read() liefert das Event: welcher Knopf wurde gedrückt?
# und values: ein Verzeichnis (genauer: Dictionary), das die Zustände
# aller GUI Elemente enthält.
event, values = window.read()
# Wenn das Event sg.WIN_CLOSED war (das Hauptfenster wurde geschlossen)
# oder der "Beenden"-Knopf gedrückt wurde...
if event == sg.WIN_CLOSED or event == "-BEENDEN-":
# springe aus der Hauptschleife
break
# Wenn der "Übertragen"-Knopf gedrückt wurde...
if event == "-UEBERTRAGEN-":
# wird der inhalt des Eingabefeldes kopiert...
text_eingabe = values["-EINGABE-"]
# und in das Ausgabefeld geschrieben
window["-AUSGABE-"].update(text_eingabe)
# Diese Zeile wird nur erreicht, wenn die Hauptschleife verlassen wurde.
# Sie schließt das Hauptfenster, falls es nicht schon geschlossen ist:
window.close()
2.3 Das erweiterte Minimalbeispiel
import PySimpleGUI as sg
sg.set_options(font=("Courier", 30),
background_color="yellow",
element_background_color="#32CD32",
button_color=('white', 'blue'))
layout = [
[sg.Input(key="-EINGABE-")],
[sg.Button("Übertragen", key="-UEBERTRAGEN-")],
[sg.Button("Testknopf", key="-TEST-")],
[sg.Combo(["Apfel", "Birne", "Banane"],
default_value="Banane",
enable_events=True,
key="-AUSWAHL-")],
[sg.Slider(range=(0, 255),
default_value=128,
orientation='h',
enable_events=True,
key="-REGLER-")],
[sg.Input(key="-AUSGABE-", disabled=True)],
[sg.Button("Beenden", key="-BEENDEN-")]
]
window = sg.Window("Minimalbeispiel",
layout,
size=(500, 450))
while True:
event, values = window.read()
# print("event:", event)
# print("values:", values)
if event == sg.WIN_CLOSED or event == "-BEENDEN-":
break
if event == "-UEBERTRAGEN-":
text_eingabe = values["-EINGABE-"]
window["-AUSGABE-"].update(text_eingabe)
if event == "-TEST-":
window["-AUSGABE-"].update("Testknopf gedrückt!")
if event == "-AUSWAHL-":
nachricht = values["-AUSWAHL-"] + " ausgewählt!"
window["-AUSGABE-"].update(nachricht)
if event == "-REGLER-":
nachricht = "Regler: " + str(values["-REGLER-"])
window["-AUSGABE-"].update(nachricht)
window.close()
2.4 Das erweiterte Minimalbeispiel, kommentiert
import PySimpleGUI as sg
sg.set_options(font=("Courier", 30),
# Farbangaben per Html-Farbnamen oder im Hex-Code:
background_color="yellow",
element_background_color="#32CD32",
# Button-Farben für gedrückt und losgelassen:
button_color=('white', 'blue'))
layout = [
[sg.Input(key="-EINGABE-")],
[sg.Button("Übertragen", key="-UEBERTRAGEN-")],
# NEU: Testknopf
[sg.Button("Testknopf", key="-TEST-")],
# NEU: Combo (=Drop-Down-Menü):
# erstes Argument immer Liste mit Auswahlmöglichkeiten
[sg.Combo(["Apfel", "Birne", "Banane"],
# Standard Wert:
default_value="Banane",
# Die Liste soll Events erzeugen bei Nutzung:
enable_events=True,
key="-AUSWAHL-")],
# NEU: Slider:
# Wertebereich:
[sg.Slider(range=(0, 255),
# Standard Wert:
default_value=128,
# Ausrichtung 'h' oder 'v':
orientation='h',
# Events bei Nutzung:
enable_events=True,
key="-REGLER-")],
# Alle Ausgaben landen hier:
[sg.Input(key="-AUSGABE-", disabled=True)],
[sg.Button("Beenden", key="-BEENDEN-")]
]
window = sg.Window("Minimalbeispiel",
layout,
size=(500, 450))
while True:
event, values = window.read()
# Die beiden folgenden Zeilen auskommentieren (# entfernen)
# um events und values zu sehen:
# print("event:", event)
# print("values:", values)
if event == sg.WIN_CLOSED or event == "-BEENDEN-":
break
if event == "-UEBERTRAGEN-":
# So kommt ihr an die Werte heran:
text_eingabe = values["-EINGABE-"]
# So kommt ihr an die Elemente heran:
window["-AUSGABE-"].update(text_eingabe)
if event == "-TEST-":
window["-AUSGABE-"].update("Testknopf gedrückt!")
if event == "-AUSWAHL-":
nachricht = values["-AUSWAHL-"] + " ausgewählt!"
window["-AUSGABE-"].update(nachricht)
if event == "-REGLER-":
nachricht = "Regler: " + str(values["-REGLER-"])
window["-AUSGABE-"].update(nachricht)
window.close()
2.5 Farbwähler
import PySimpleGUI as sg
sg.set_options(font=("Courier", 30))
layout = [[sg.Slider(range=(0, 255), default_value=255, orientation="h", key="-RED-")],
[sg.Slider(range=(0, 255), default_value=0, orientation="h", key="-GREEN-")],
[sg.Slider(range=(0, 255), default_value=0, orientation="h", key="-BLUE-")],
[sg.Button("Beenden", key="-QUIT-")]
]
window = sg.Window("Farbmixer", layout)
def rgb_to_hex(r, g, b):
return "#{:02x}{:02x}{:02x}".format(r, g, b)
while(True):
event, values = window.read(timeout=100)
if event == sg.WIN_CLOSED or event == "-QUIT-":
break
red = int(values["-RED-"])
green = int(values["-GREEN-"])
blue = int(values["-BLUE-"])
color = rgb_to_hex(red, green, blue)
window["-QUIT-"].update(button_color=('white', color))
window.close()
2.6 Farbwähler, kommentiert
import PySimpleGUI as sg
sg.set_options(font=("Courier", 30))
layout = [[sg.Slider(range=(0, 255), orientation="h", key="-RED-")],
[sg.Slider(range=(0, 255), orientation="h", key="-GREEN-")],
[sg.Slider(range=(0, 255), orientation="h", key="-BLUE-")],
[sg.Button("Beenden", key="-QUIT-")]
]
window = sg.Window("Farbmixer", layout)
# Diese Funktion wandelt drei Werte für rot, grün und blau
# in den ensprechenden Hex String um:
def rgb_to_hex(r, g, b):
return "#{:02x}{:02x}{:02x}".format(r, g, b)
while(True):
# timeout=100 sorgt dafür, dass die values 10 mal
# pro Sekunde ausgelesen werden, anstatt auf eine
# Eingabe zu warten:
event, values = window.read(timeout=100)
if event == sg.WIN_CLOSED or event == "-QUIT-":
break
# Die Werte der Slider sind float, also Dezimalzahlen.
# Sie müssen noch in ganze Zahlen (int) umgewandelt werden.
# Das erledigt die Funktion int():
red = int(values["-RED-"])
green = int(values["-GREEN-"])
blue = int(values["-BLUE-"])
# Wir nutzen die oben definierte Funktion, um den hex-Wert zu erhalten:
color = rgb_to_hex(red, green, blue)
# Wir schnappen uns den Quit-Button per window["-QUIT-"]
# und ändern die Farbe mit .update(button_color=(...)):
window["-QUIT-"].update(button_color=('white', color))
window.close()
3. Projekt Bildbearbeitung
3.1 Bild laden und anzeigen
import PySimpleGUI as sg
import cv2
layout = [
[sg.Image(key="-IMAGE-")],
[sg.Button("Bild laden"), sg.Button("Beenden")]
]
window = sg.Window("Bild laden und anzeigen", layout)
while True:
event, values = window.read()
if event == sg.WINDOW_CLOSED or event == "Beenden":
break
if event == "Bild laden":
filename = sg.popup_get_file("Bild laden", no_window=True)
if filename:
image = cv2.imread(filename)
image_bytes = cv2.imencode('.png', image)[1].tobytes()
window["-IMAGE-"].update(data=image_bytes)
window.close()
3.2 Bild laden und anzeigen, kommentiert
import PySimpleGUI as sg
import cv2
layout = [
[sg.Image(key="-IMAGE-")],
[sg.Button("Bild laden"), sg.Button("Beenden")]
]
window = sg.Window("Bild laden und anzeigen", layout)
while True:
event, values = window.read()
if event == sg.WINDOW_CLOSED or event == "Beenden":
break
if event == "Bild laden":
# popup_get_file öffnet ein Filedialog-Fenster zur Auswahl
# einer Bilddatei.
# Der Rückgabewert ist der Pfad zur Datei!
filename = sg.popup_get_file("Bild laden", no_window=True)
# Wenn es geklappt hat (also filename nicht None ist) ...
if filename:
# wird das Bild geladen...
image = cv2.imread(filename)
# und zur Darstellung konvertiert...
image_bytes = cv2.imencode('.png', image)[1].tobytes()
# und im GUI-Element -Image- angezeigt
window["-IMAGE-"].update(data=image_bytes)
window.close()
3.4 Kachel ausschneiden und Farbkanäle einzeln anzeigen
import PySimpleGUI as sg
import cv2
import numpy as np
sg.set_options(font=("Courier", 30))
layout = [
[sg.Image(key="-IMAGE-")],
[sg.Button("Bild laden"), sg.Button("Beenden")]
]
window = sg.Window("Bild laden und anzeigen", layout)
# NEU: Wir verlagern das umwandeln und anzeigen des Bildes
# in eine Funktion:
def show_image(image):
image_bytes = cv2.imencode('.png', image)[1].tobytes()
window["-IMAGE-"].update(data=image_bytes)
while True:
event, values = window.read()
if event == sg.WINDOW_CLOSED or event == "Beenden":
break
if event == "Bild laden":
filename = sg.popup_get_file("Bild laden", no_window=True)
if filename:
image = cv2.imread(filename)
kachel = image[200:400, 200:400]
kachel_b = kachel[:,:,0]
kachel_g = kachel[:,:,1]
kachel_r = kachel[:,:,2]
image = np.zeros((200, 600, 3))
image[:,0:200,0] = kachel_b
image[:,200:400,1] = kachel_g
image[:,400:600,2] = kachel_r
show_image(image)
window.close()
