Zum Inhalt

Mini-Projekt

Nützliche Beispiele

Grafik mit GPanel

GPanel ist eine einfache Python Bibliothek zum Zeichnen ohne die Schildkröte u.a. mit Animationen. Aber GPanel funktioniert nicht auf der "schule.gitreh" Seite!

Das Grundprinzip von GPanel ist eine Zeichenfläche mit einer definierten Breite und Höhe. Die Zeichenfläche ist mit einem 2D-Koordinatensystem ausgestattet (x von Links nach Rechts und y von Unten nach Oben). Um die Zeichenfläche zu erhalten verwenden wir die Funktion makeGPanel.

from gpanel import *
makeGPanel()
So entsteht ein Koordinatensystem mit x/y-Koordinaten von 0 bis 1. Der Startpunkt zum Zeichnen ist in der Mitte bei 0/0.

Das Koordinatensystem kann freigewählt werden mit makeGPanel(xmin, xmax, ymin, ymax).

Absolutes und relatives Zeichnen

Mit GPanel können Formen und Figuren entweder mit absolutem Bezug zum Koordinatensystem gezeichnet werden. Z.B. zeichnet das folgende Program zwei Linien mit absoluten Koordinaten:

from gpanel import *
makeGPanel()
# x1, y1, x2, y2
line(0.1, 0.1, 0.1, 0.9) 
line(0.2, 0.1, 0.2, 0.9) 
Alternativ kann relativ zur aktuellen "Position" gezeichnet werden: Ein wichtiges Konzept ist dabei der sogenannte Cursor, dies ist wie eine "unsichtbare Schildkröte", die aktuelle Stelle ab der gezeichnet wird.
from gpanel import *
makeGPanel()
# x1, y1
lineTo(0.1, 0.9) 
lineTo(0.3, 0.1)
Die aktuelle Cursor Position kann mit dem Befehl pos(x,y) verschoben werden.

Tastatur und Mauseingabe

Erst richtig interessant wird das Zeichnen mit GPanel, wenn die Maus oder Tastatur für die Eingabe verwendet werden kann. Wie dies genau funktioniert aus technischer Sicht ist ein bisschen kompliziert. Kurzgesagt: es können zwei Funktionen definiert werden, die jeweils aufgerufen werden, wenn etwas mit der Maus passiert, oder eine Taste gedrückt wird. So eine Funktion nennt sich auch "Callback".

Mausklicks

from gpanel import *

def onMousePressed(x, y):
    pos(x, y)    
    fillCircle(1)

makeGPanel(0, 20, 0, 20, mousePressed = onMousePressed)
setColor("cyan")

Mausbewegung

Auch nützlich ist das Abfangen von Mausbewegungen:

from gpanel import *

def onMouseMoved(x, y):
    draw(x, y)

makeGPanel(mouseMoved = onMouseMoved)
Falls nur Maus Bewegungen bei gedrückter Maustaste gesucht sind: mouseDragged= setzen.

Tastatur

Mit dem folgenden Programm wird eine Funktion aufgerufen, sobald eine Taste gedrückt wird.

from gpanel import *

x = 0
y = 0

def drawCircle():
    setColor("red")
    fillCircle(4)
    setColor("black")
    circle(4)
    move(x, y)

def onKeyPressed(keyCode):
    global x, y

    print("Gedrückter Buchstabe: ", keyCode, chr(keyCode))
    if keyCode == 38:
        y += 2 
    elif keyCode == 40:
        y -= 2
    elif keyCode == 37:
        x -= 2
    elif keyCode == 39:
        x += 2      
    drawCircle()

makeGPanel(-100, 100, -100, 100, keyPressed = onKeyPressed)
text(-95, -95, "Press the cursor keys!")

Mit diesem Programm wird mithilfe einer Schleife auf Tastatureingaben gewartet. Die Funktion getKeyCodeWait() pausiert das Programm bis eine Taste gedrückt wird (ähnlich wie input()).

from gpanel import *

makeGPanel(-10, 10, -10, 10)

text(-9, -9, "Press the key r, b or g.")

# oder:
#while True:
for i in range(10): # anzahl runden...
    key = getKeyCodeWait()
    print(key)
    if key == 82:
        setColor("red")
    elif key == 66:
        setColor("blue")
    elif key == 71:
        setColor("green")    
    fillCircle(3)

Wenn man das Programm nicht pausieren möchte, können Tastatureingaben mit kbhit und getKeyCode abgefragt werden.

from gpanel import *

makeGPanel(-60, 60, -60, 60)
text(-58, -58, "Press the cursor keys!")

x = 0
y = 0

setColor("green")  


# Endlosschleife
while True: 
    if kbhit():
        keyCode = getKeyCode()
        buchstabe = chr(keyCode)
        if buchstabe == "W":
            y += 1        
        elif buchstabe == "S":
            y -= 1 
        elif buchstabe == "A":
            x -= 1 
        elif buchstabe == "D":
            x += 1

    move(x, y)
    fillCircle(1)
    delay(10) # 10 ms warten

Daten

Um mit Daten und Zeiten zu arbeiten, bietet Python spezielle Funktionen.

from datetime import date

# Heutiges Datum
heute = date.today()
print("Heute: ", heute)

# 'Datum' erstellen
semester_start = date(2025, 2, 24)
print("Start: ", semester_start)

# Differenz von Daten
differenz_datum = heute - semester_start
vergangene_tage = differenz_datum.days
print(vergangene_tage)


# 'Datum' aus Zeichenkette lesen
from datetime import datetime
# Achtung: funktioniert nicht in 'WebTigerJython'
ein_datum = datetime.strptime('2.3.2020', '%d.%m.%Y').date() # %d steht für Tag, %m für Monat als Zahl, %Y für Jahr
print(ein_datum)

Entwicklungsumgebungen

Name Link Beschreibung gturtle gpanel iPad
schule.gitreh IDE, IDE - Turtle Unser online programmierbuch X X
WebTigerJython WebTigerJython eingeschränkte Browser Entwicklungsumgebung (startet schnell) X X X
WebTigerPython WebTigerPython Browser Entwicklungsumgebung (startet langsam) X X X
TigerPython TigerJython - Download umfangreiche Lernumgebung, kann alles von WebTigerJython & WebTigerPython und mehr X X
PyCharm PyCharm - Download professionelle Entwicklungsumgebung

Nützliche Befehle: Referenz

GPanel: allgemein

Befehl Aktion
makeGPanel() erzeugt ein (globales) GPanel-Grafikfenster mit Koordinaten (0, 1, 0, 1). Cursor auf (0, 0)
makeGPanel(xmin, xmax, ymin, ymax) erzeugt ein (globales) GPanel-Grafikfenster mit angegebenen Koordinaten. Cursor auf (0, 0)
getScreenWidth() gibt Bildschirmbreite zurück (in Pixels)
getScreenHeight() gibt Bildschirmhöhe zurück (in Pixels)
bgColor(color) setzt die Hintergrundfarbe (X11-Farbstring oder Color type, zurückgegeben von makeColor())
makeColor(colorStr) gibt Farbe als Color type zum gegebenen X11-Farbstring zurück
delay(time) Programm um Zeit time (Millisekunden) anhalten
dispose() schliesst das Fenster
clear() löscht Fensterinhalt (füllt mit Hintergrundfarbe) und setzt Cursor auf (0, 0)
erase() löscht Fensterinhalt (füllt mit Hintergrundfarbe) ohne Veränderung des Cursors

GPanel: zeichnen

Befehl Aktion
lineWidth(width) setzt die Stiftdicke (in Pixel)
setColor(color) setzt die Stiftfarbe (X11-Farbstring oder Colortype)
move(x, y) setzt Cursor auf (x, y) ohne zu zeichnen
getPosX() liefert x-Koordinate des Cursors
getPosY() liefert y-Koordinate des Cursors
getPos() liefert  Cursorposition als Punktliste
pos(x,y) setzt den Cursor auf den Punkt x/y
draw(x, y), lineTo(x, y), lineto(x, y) zeichnet Linie zu neuem Punkt (x, y) und ändert Cursor
draw(coord_list), lineTo(coord_list), lineto(coord_list) zeichnet Linie zu Punktliste = [x, y] und ändert Cursor
line(x1, y1, x2, y2) zeichnet Linie von (x1, y1) zu (x2, y2) ohne Änderung des Cursors
line(pt1, pt2) zeichnet Linie von pt1 = [x1, y1] zu pt2 = [x2, y2] ohne Änderung des Cursors
line(li[p0, p1, ..]) zeichnet Linienzug der Punkte in der Liste (auch Tupel)
circle(radius) zeichnet Kreis mit Mitte bei Cursor und gegebenem Radius
fillCircle(radius) zeichnet gefüllten Kreis (Füllfarbe = Stiftfarbe)
ellipse(a, b) zeichnet Ellipse mit Mitte bei Cursor und Halbachsen
fillEllipse(a, b) zeichnet gefüllte Ellipse (Füllfarbe = Stiftfarbe)
rectangle(a, b) zeichnet Rechteck mit Zentrum bei Cursor und Seiten
rectangle(x1, y1, x2, y2) zeichnet Rechteck mit gegenüberliegenden Eckpunkten
rectangle(pt1, pt2) zeichnet Rechteck mit gegenüberliegenden Punktlisten
fillRectangle(a, b) zeichnet gefülltes Rechteck (Füllfarbe = Stiftfarbe)
fillRectangle(x1, y1, x2, y2) zeichnet gefülltes Rechteck (Füllfarbe = Stiftfarbe)
fillRectangle(pt1, pt2) zeichnet gefülltes Rechteck (Füllfarbe = Stiftfarbe)
arc(radius, startAngle, extendAngle) zeichnet Kreisbogen mit Zentrum bei Cursor, Radius und Start- und Sektorwinkel (0 nach Osten, positiv im Gegenuhrzeigersinn)
fillArc(radius, startAngle, extendAngle) zeichnet gefüllten Kreisbogen (Füllfarbe = Stiftfarbe)
polygon(x_list, y_list) zeichnet Polygon mit Eckpunkten mit x-Koordinaten aus der Liste x_list und y-Koordinaten aus  y_list
polygon((li[pt1, pt2,..]) zeichnet Polygon mit Liste aus Eckpunktlisten pt1, pt2,...
fillPolygon(x_list, y_list) zeichnet gefülltes Polygon (Füllfarbe = Stiftfarbe)
fillPolygon((li[pt1, pt2,..]) zeichnet gefülltes Polygon (Füllfarbe = Stiftfarbe)
triangle(x1, y1, x2, y2, x3, y3) zeichnet Dreieck mit Eckpunkten
triangle(pt1, pt2, pt3) zeichnet Dreieck mit Eckpunktlisten
triangle(li[pt1, pt2, pt3]) zeichnet Dreieck mit Liste der Eckpunkte
fillTriangle(x1, y1, x2, y2, x3, y3) zeichnet gefülltes Dreieck (Füllfarbe = Stiftfarbe)
fillTriangle(pt1, pt2, pt3) zeichnet gefülltes Dreieck (Füllfarbe = Stiftfarbe)
fillTriangle(li[pt2, pt2, pt3]) zeichnet gefülltes Dreieck (Füllfarbe = Stiftfarbe)
point(x, y) zeichnet 1-Pixel-Punkt bei (x, y)
point(pt) zeichnet 1-Pixel-Punkt bei Punktliste pt = [x,y]
fill(x, y, color, replacementColor) füllt geschlossenes Gebiet um Punkt (x, y). color wird durch replacementColor ersetzt (floodfill)
fill(pt, color,replacementColor) füllt geschlossenes Gebiet um Punkt pt. color wird durch replacementColor ersetzt (floodfill)
image(path, x, y) fügt eine Bild im GIF- , PNG- oder JPG-Format mit unterer linker Ecke bei (x, y) ein. Pfad zur Bilddatei: Relativ zum Verzeichnis von TigerJython, im Distributions-JAR (Verzeichnis sprites) oder mit http:// vom Internet.
image(path, pt) dasselbe mit Punktliste
imageHeigh(path) gibt die Bildhöhe zurück
imageWidth(path) gibt die Bildbreite zurück
enableRepaint(boolean) aktiviert/deaktiviert das automatische Rendern des Offscreen-Buffers (Standard: aktiviert)
repaint() rendert den Offscreen-Buffer (nötig, wenn das automatische Rendern deaktiviert ist)
getPixelColor(x, y) gibt Farbe am Punkt (x, y) als Color type zurück
getPixelColor(pt) gibt Farbe an Punktliste pt = [x, y] als Color type zurück
getPixelColorStr(x, y) gibt Farbe am Punkt (x, y) als X11-Farbstring zurück
getPixelColorStr(pt) gibt Farbe an Punktliste als X11-Farbstring zurück
makeColor(value) gibt eine Farbreferenz von value zurück. Werte-Beispiele: ("7FFED4"), ("Aqua-Marine"), (0x7FFED4), (8388564), (0.5, 1.0, 0.83), (128, 255, 212), ("rainbow"", n) mit n = 0..1, Lichtspektrum

GPanel: Tastatur

Befehl Aktion
getKey() holt den letzten Tastendruck ab und liefert String zurück (leer, falls illegale Taste)
getKeyCode() holt den letzten Tastendruck ab und liefert Code zurück
getKeyWait() wartet bis Taste gedrückt und liefert String zurück (leer, falls illegale Taste)
getKeyCodeWait() wartet bis Taste gedrückt und liefert Code zurück
kbhit() liefert True, falls ein Tastendruck noch nicht mit getKey() od. getKeyCode() abgeholt ist

GPanel: Text

Befehl Aktion
text(string) schreibt Text mit Beginn beim aktuellen Cursor
text(x, y, string) schreibt Text mit Beginn bei Punkt (x, y)
text(pt, string) schreibt Text mit Beginn bei Punktliste pt = [x, y]
text(x, y, string, font, textColor, bgColor) schreibt Text mit Beginn bei (x, y) mit Font, Textfarbe und Hintergrundfarbe
text(pt, string, font, textColor, bgColor) schreibt Text mit Beginn bei Punkliste mit Font, Textfarbe und Hintergrundfarbe
font(schrift) setzt eine neue Standardschrift (Font)
Font(name, style, size) erzeugt eine 'Schrift' mit gegebenen Namen, Stil und Grösse:
name: ein String mit einem dem System bekannten Fontnamen, z.B.. "Times New Roman", "Arial", "Courier"

style: einer der Konstanten: Font.PLAIN, Font.BOLD, Font.ITALIC oder einen Kombination davon: Font.BOLD + Font.ITALIC
size: ein Integer mit einer auf dem System verfügbaren Font-Grösse (in pixels), z.B. 12, 16, 72

GPanel: Callbacks

Befehl Aktion
makeGPanel(mouseNNN = onMouseNNN)

auch mehrere, durch Komma getrennt
registriert die Callbackfunktion onMouseNNN(x, y), die beim Mausevent aufgerufen wird. Werte für NNN: Pressed, Released, Clicked, Dragged, Moved, Entered, Exited, SingleClicked, DoubleClicked
makeGPanel(keyPressed = onKeyPressed) registriert die Callbackfunktion onKeyPressed(keyCode), die beim Drücken einer Tastaturtaste aufgerufen wird. keyCode ist ein für die Taste eindeutiger integer Code
getKeyModifiers() liefert nach einem Tastaturevent einen Code für Spezialtasten (Shift, Ctrl, usw., auch kombiniert)