Logo des digitalen Schulbuchs inf-schule.de. Schriftzug in Zustandsübergangsdiagramm eines endlichen Automaten.

Verarbeitung von Ereignissen

Zielsetzung

Die Würfel sollen durch einen Doppelklick auf die entsprechenden Textfelder einzeln aktiviert werden können.

Anwendungsfenster

Ereignisse und ihre Verarbeitung

Das folgende Testprogramm zeigt, wie man Prozeduren zur Ereignisverarbeitung an GUI-Objekte anbinden kann.

from tkinter import *
from random import randint
# Ereignisverarbeitung

def wuerfelAWerfen(event):
    # Verarbeitung der Daten
    wuerfelA = randint(1, 6)
    # Anzeige der Daten
    labelWuerfelA.config(text=str(wuerfelA))

def alleWuerfelWerfen(event):
    # Verwaltung und Verarbeitung der Daten
    from random import randint
    wuerfelA = randint(1,6)
    wuerfelB = randint(1,6)
    wuerfelC = randint(1,6)
    # Anzeige der Daten
    labelWuerfelA.config(text=str(wuerfelA))
    labelWuerfelB.config(text=str(wuerfelB))
    labelWuerfelC.config(text=str(wuerfelC))

# Erzeugung des Fensters
tkFenster = Tk()
tkFenster.title("Test")
tkFenster.geometry('120x110')
# Rahmen Würfel
frameWuerfel = Frame(master=tkFenster,
                     background="#FBD975")
frameWuerfel.place(x=5, y=5, width=110, height=100)
# Label mit Überschrift für die Würfel
labelUeberschriftWuerfel = Label(master=frameWuerfel,
                                 text="Würfel",
                                 background="white")
labelUeberschriftWuerfel.place(x=5, y=5, width=100, height=20)
# Label Würfel A
labelWuerfelA = Label(master=frameWuerfel,
                      text="1",
                      background="white")
labelWuerfelA.bind("<Double-Button-1>", wuerfelAWerfen)
labelWuerfelA.place(x=5, y=35, width=30, height=30)
# Label Würfel B
labelWuerfelB = Label(master=frameWuerfel,
                      text="1",
                      background="white")
labelWuerfelB.place(x=40, y=35, width=30, height=30)
# Label Würfel C
labelWuerfelC = Label(master=frameWuerfel,
                      text="1",
                      background="white")
labelWuerfelC.place(x=75, y=35, width=30, height=30)
# Button zum Würfeln
buttonWuerfel = Button(master=frameWuerfel,
                        text="Wuerfel werfen")
buttonWuerfel.bind("<Button-1>", alleWuerfelWerfen)
buttonWuerfel.place(x=5, y=75, width=100, height=20)

# Aktivierung des Fensters
tkFenster.mainloop()

Es sind hier zwei Möglichkeiten realisiert, Würfel zu aktivieren. Man kann alle Würfel werfen, indem man die Schaltfläche anklickt. Den ersten Würfel (ganz links) kann man zudem durch einen Doppelklick auf das entsprechende Textfeld aktivieren.

Test

Zur Ereignisverarbeitung müssen drei Festlegungen getroffen werden.

Zunächst muss das Ereignis beschrieben werden. Hierzu gibt es in tkinter bestimmte Zeichenketten wie z. B. "<Double-Button-1>" für einen Doppelklick, die für die Ereignisbeschreibung vorgesehen sind.

Als nächstes muss die Prozedur zur Ereignisverarbeitung (der sogenannte Eventhandler) definiert werden. Diese Prozedur legt fest, mit welchen Aktionen das System auf das auslösende Ereignis reagiert.

Als letztes muss das Ereignis mit dem Eventhandler verbunden werden. Hierzu wird die Operation bind des betreffenden GUI-Objekts aufgerufen.

Aufgabe 1

Ergänze das chuck-a-luck-Programm so, dass man alle Würfel dort separat aktivieren kann.

Aufgabe 2

Das folgende Programm reagiert auf eine Reihe verschiedenster Ereignisse.

# Ereignisverarbeitung

def linksVerschieben(event):
    (x0, y0, x1, y1) = tuple(canvas.coords(id_kreis))
    if x0 >= 10:
        canvas.coords(id_kreis, (x0-10, y0, x1-10, y1))

def rechtsVerschieben(event):
    (x0, y0, x1, y1) = tuple(canvas.coords(id_kreis))
    if x1 <= 580:
        canvas.coords(id_kreis, (x0+10, y0, x1+10, y1))

def obenVerschieben(event):
    (x0, y0, x1, y1) = tuple(canvas.coords(id_kreis))
    if y0 >= 10:
        canvas.coords(id_kreis, (x0, y0-10, x1, y1-10))

def untenVerschieben(event):
    (x0, y0, x1, y1) = tuple(canvas.coords(id_kreis))
    if y1 <= 380:
        canvas.coords(id_kreis, (x0, y0+10, x1, y1+10))

def objektLoeschen(event):
    canvas.delete(id_kreis)

def vergroessern(event):
    (x0, y0, x1, y1) = tuple(canvas.coords(id_kreis))
    canvas.coords(id_kreis, (x0, y0, x1+10, y1+10))

def verkleinern(event):
    (x0, y0, x1, y1) = tuple(canvas.coords(id_kreis))
    if x1-x0 > 10 and y1-y0 > 10:
        canvas.coords(id_kreis, (x0, y0, x1-10, y1-10))

def plazieren(event):
    (x, y) = (event.x, event.y)
    (x0, y0, x1, y1) = tuple(canvas.coords(id_kreis))
    canvas.coords(id_kreis, (x, y, x+(x1-x0), y+(y1-y0)))

def entfernen(event):
    (x, y) = (event.x, event.y)
    (x0, y0, x1, y1) = tuple(canvas.coords(id_kreis))
    if x0 <= x and x <= x1 and y0 <= y and y <= y1:
        canvas.delete(id_kreis)

# Erzeugung der Komponenten

from tkinter import *
tkFenster = Tk()
tkFenster.title("Leinwand")
tkFenster.geometry("600x400")
# Zeichenleinwand
canvas = Canvas(master=tkFenster, background="white")
canvas.place(x=5, y=5, width=590, height=390)
# Grafikobjekte
id_kreis = canvas.create_oval(100, 100, 120, 120, fill="red")
# Ereignisse
tkFenster.bind("<KeyPress-g>", vergroessern)
tkFenster.bind("<KeyPress-k>", verkleinern)
tkFenster.bind("<KeyPress-Up>", obenVerschieben)
tkFenster.bind("<KeyPress-Down>", untenVerschieben)
tkFenster.bind("<KeyPress-Left>", linksVerschieben)
tkFenster.bind("<KeyPress-Right>", rechtsVerschieben)
canvas.bind("<Button-1>", plazieren)
canvas.bind("<Button-3>", entfernen)

# Aktivierung der Ereignisschleife
tkFenster.mainloop()

(a) Teste, wie das Programm reagiert, wenn man die Pfeiltasten drückt / die Tasten [g] und [k] drückt / die linke Maustaste anklickt und der Mauszeiger sich irgendwo auf der Leinwand befindet / die rechte Maustaste anklickt und der Mauszeiger sich außerhalb bzw innerhalb der Kreisbox befindet.

(b) Versuche, durch Analyse des Quelltextes und gezielter Experimente herauszufinden, wie die Ereignisse und ihre Verarbeitung in Python implementiert sind.

(c) Verändere und ergänze das Programm nach deinen Wünschen.

X

Fehler melden

X

Suche