Präsentation herunterladen
Die Präsentation wird geladen. Bitte warten
1
Grafische Benutzeroberflächen
Klaus Becker 2009
2
Grafische Benutzeroberflächen
Inhalte: Benutzerfreundlichkeit Aufbau und Verhalten GUI-Entwicklung (mit Tkinter) GUI-Objekte und Datenmodell-Objekte GUI-Entwicklung mit Werkzeugen
3
Benutzerfreundlichkeit
Teil 1 Benutzerfreundlichkeit
4
Einstieg - Anhalteweg eines Autos
Reaktionsweg = (Geschwindigkeit [in km/h] / 10) * 3 Bremsweg = (Geschwindigkeit [in km/h] / 10)2 Anhalteweg = Reaktionsweg + Bremsweg textbasierte, synchronisierte Benutzeroberfläche multimediale, asynchrone Benutzeroberfläche
5
Fachkonzept - Software-Ergonomie
Die Software-Ergonomie befasst sich mit der Gestaltung benutzerfreundlicher Computer-Programme. Ziel ist es, die Zusammenarbeit zwischen Mensch und Maschine so zu gestalten, dass nicht der Mensch sich an den Gegebenheiten der Maschine orientieren muss, sondern dass umgekehrt die Maschine eine Kommunikationsschnittstelle zur Verfügung stellt, die sich an den Bedürfnissen der sie bedienenden Menschen orientiert. Kriterien zur Beschreibung von Benutzerfreundlichkeit: Aufgabenangemessenheit: Das Programm konzentriert sich auf die eigentliche Aufgabe und minimiert unnötiger Interaktionen. Selbstbeschreibungsfähigkeit: Der Programm liefert die zur Bedienung erforderlichen Hilfen und Rückmeldungen. Steuerbarkeit: Das Programm gibt dem Benutzer die Möglichkeit, mit Hilfe von Dialogen den Ablauf zu steuern. Erwartungskonformität: Das Programm ist auf die Erwartungen der intendierten Benutzer abgestimmt. Fehlertoleranz: Das Programm erkennt fehlerhafte Bedienungen und hilft bei der Korrektur. Individualisierbarkeit: Das Programm lässt sich an individuelle Bedürfnisse anpassen. Lernförderlichkeit: Das Programm unterstützt den Benutzer beim Erlernen der Funktionalitäten.
6
Übungen (siehe ) Beurteilen Sie die im Einstieg gezeigten Programme hinsichtlich der Kriterien für Benutzerfreundlichkeit.
7
Teil 2 Aufbau und Verhalten
8
Einstieg - Analyse einer GUI
Ziel ist es herauszufinden, wie eine graphische Benutzeroberfläche (GUI) aufgebaut ist und wie ihr Verhalten zustande kommt. Bearbeiten Sie die Aufgaben des Abschnitts # -*- coding: iso *- from Tkinter import * # Ereignisverarbeitung def Button_Berechnen_Click(): # Übernahme der Daten geschwindigkeit = float(entryGeschwindigkeit.get()) # Verarbeitung der Daten reaktionsweg = (geschwindigkeit/10)*3 bremsweg = (geschwindigkeit/10) * (geschwindigkeit/10) anhalteweg = reaktionsweg + bremsweg # Anzeige der Daten anzeigeReaktionsweg = '%.2f'%(reaktionsweg) labelWertReaktionsweg.config(text=anzeigeReaktionsweg) anzeigeBremsweg = '%.2f'%(bremsweg) labelWertBremsweg.config(text=anzeigeBremsweg) anzeigeAnhalteweg = '%.2f'%(anhalteweg) labelWertAnhalteweg.config(text=anzeigeAnhalteweg) # Erzeugung des Fensters tkFenster = Tk() tkFenster.title("Anhalteweg") tkFenster.geometry('300x287') # Rahmen für die Überschrift frameUeberschrift = Frame(master=tkFenster, background="#889E9D") frameUeberschrift.place(x=5, y=5, width=290, height=45) ... Auszug aus dem Quelltext G(raphical) U(ser) I(interface)
9
Fachkonzept - GUI Eine grafische Benutzeroberfläche (auch kurz GUI für Graphical User Interface) ist aus Komponenten aufgebaut. Jede Komponente wird mit einem grafische Symbol dargestellt.
10
Fachkonzept - GUI-Komponente
Grafische Benutzeroberflächen können u. a. folgende Komponenten haben: Fenster: Eine GUI kann aus einem oder mehreren Fenstern bestehen. Rahmen / Tafel: Rahmen (bzw. Tafeln) dienen als Behälter für andere Komponenten. Schaltfäche (Button): Mit Schaltflächen werden in der Regel Programmaktionen ausgelöst. Schriftfeld (Label): Schriftfelder dienen dazu, Texte auf dem Bildschirm darzustellen. Eingabefeld: In Eingabefelder kann der Benutzer Zeichenketten eingeben. Leinwand (Canvas): Eine Leinwand ist ein Bereich, in dem man z. B. Figuren zeichnen und Bilder anzeigen kann Textfeld: Ein Textfeld ist ein Eingabebereich, in den mehrzeilige Texte geschrieben werden können. ...
11
Fachkonzept - GUI-Objekt
Ein Objekt ist eine Einheit, die Daten verwalten und verarbeiten kann. Jedes Objekt ist einer Klasse zugeordnet. Diese legt den Aufbau des Objekts genau fest. Ein Objekt muss erzeugt werden, bevor es zur Datenverwaltung und -verarbeitung benutzt werden kann. Die zugehörige Klasse liefert den hierzu benötigten Bauplan. Komponenten einer Benutzeroberfläche werden programmtechnisch durch Objekte (im Sinne der objektorientierten Programmierung) dargestellt. Zu jeder Komponente gibt es ein entsprechendes GUI-Objekt, das die Daten und Operationen der Komponente verwaltet.
12
Fachkonzept - GUI-Objekt
objektname = GUIKlasse(...) Erzeugung eines GUI-Objekts ... # Erzeugung des Fensters tkFenster = Tk() ... # Rahmen für die Überschrift frameUeberschrift = Frame(master=tkFenster, background="#889E9D") ... # Eingabefeld für die Geschwindigkeit entryGeschwindigkeit = Entry(master=frameEingaben) ... # Schaltfläche Berechnen buttonBerechnen = Button(master=frameVerarbeitung, text="berechnen", command=...) ... # Label für den Wert des Reaktionswegs labelWertBremsweg = Label(master=frameAusgaben, background="white", text="") ...
13
Fachkonzept - GUI-Objekt
GUI-Komponenten haben Eigenschaften wie z. B. eine bestimmte Hintergrundfarbe. Zur Verwaltung solcher Eigenschaften haben die zugehörigen Objekte Attribute, denen ein bestimmter Wert zugewiesen werden kann. Attribute Attributwerte ... # Label für die Überschrift labelUeberschrift = Label(master=frameUeberschrift, \ background="white", \ text="Anhalteweg eines Autos") ...
14
Fachkonzept - GUI-Objekt
Zur Verarbeitung der verwalteten Daten stellen Objekte Operationen (man sagt auch Methoden) bereit. objektname.operation Aktivierung einer Operation def Button_Berechnen_Click(): # Übernahme der Daten geschwindigkeit = float(entryGeschwindigkeit.get()) # Verarbeitung der Daten reaktionsweg = (geschwindigkeit/10)*3 bremsweg = (geschwindigkeit/10) * (geschwindigkeit/10) anhalteweg = reaktionsweg + bremsweg # Anzeige der Daten anzeigeReaktionsweg = '%.2f'%(reaktionsweg) labelWertReaktionsweg.config(text=anzeigeReaktionsweg) anzeigeBremsweg = '%.2f'%(bremsweg) labelWertBremsweg.config(text=anzeigeBremsweg) anzeigeAnhalteweg = '%.2f'%(anhalteweg) labelWertAnhalteweg.config(text=anzeigeAnhalteweg) Objekt Operation
15
Fachkonzept - Ereignissteuerung
Aktionen des Benutzers wie z. B. das Anklicken einer Schaltfläche lösen Ereignisse aus. Ein Ereignis ist eine Zustandsänderung in einem Objekt, die von Interesse ist und daher mit einer Prozedur zur Ereignisverarbeitung verknüpft werden kann. wiederhole: wenn ein Ereignis eintritt: führe die zugeordneten Prozedur zur Ereignisverarbeitung aus Ereignisschleife def Button_Berechnen_Click(): ... # Erzeugung des Fensters tkFenster = Tk() buttonBerechnen = Button(master=frameVerarbeitung, \ text="berechnen", \ command=Button_Berechnen_Click) # Aktivierung des Fensters tkFenster.mainloop() Ereignisverarbeitungsprozedur Aktierung der Ereignisschleife
16
Fachkonzept - Laufzeitfehler
Laufzeitfehler sind Fehlersituationen, die während der Ausführung eines Programms auftreten. Beispiele: - Eine Operation soll mit Daten ausgeführt werden, deren Typ nicht passt. - Eine Division durch 0 soll ausgeführt werden. - Eine Datei soll geladen werden, die nicht vorhanden ist. - ... >>> Exception in Tkinter callback Traceback (most recent call last): File ... return self.func(*args) File ... in Button_Berechnen_Click geschwindigkeit = float(entryGeschwindigkeit.get()) ValueError: invalid literal for float(): gering
17
try-except-Anweisung
def Button_Berechnen_Click(): try: # Übernahme der Daten geschwindigkeit = float(entryGeschwindigkeit.get()) # Verarbeitung der Daten reaktionsweg = (geschwindigkeit/10)*3 bremsweg = (geschwindigkeit/10) * (geschwindigkeit/10) anhalteweg = reaktionsweg + bremsweg # Anzeige der Daten anzeigeReaktionsweg = '%.2f'%(reaktionsweg) labelWertReaktionsweg.config(text=anzeigeReaktionsweg) anzeigeBremsweg = '%.2f'%(bremsweg) labelWertBremsweg.config(text=anzeigeBremsweg) anzeigeAnhalteweg = '%.2f'%(anhalteweg) labelWertAnhalteweg.config(text=anzeigeAnhalteweg) except: entryGeschwindigkeit.delete(0, END) try: [Anweisungen] except:
18
Übungen (siehe ) Bearbeiten Sie die Aufgaben des Abschnitts
19
Teil 3 Entwicklung
20
Einstieg - "chuck a luck" Der Spieler / die Spielerin zahlt zuerst einen Dollar (Cent) als Einsatz. Diesen setzt er / sie auf eine Zahl des Spielfeldes. Anschließend wirft er / sie drei Würfel. Jetzt wird bestimmt, wie viele Würfel mit der gesetzten Spielzahl übereinstimmen. Gibt es keine Übereinstimmungen, dann ist der Einsatz verloren. Ansonsten wird erhält der Spieler / die Spielerin den Einsatz zurück und zusätzlich für jede Übereinstimmung einen Dollar (Cent).
21
Zielsetzung und Vorgehensweise
Es soll ein Programm zur Simulation des Spiels chuck-a-luck entwickelt werden. Über eine grafische Benutzeroberfläche soll der Spieler / die Spielerin die Spielaktionen durchführen können. Das Programm soll selbstbeschreibend und fehlertolerant gestaltet werden. Gehen Sie den Abschnitt "GUI-Entwicklung mit Tkinter" (siehe ) Schritt für Schritt durch und entwickeln Sie parallel dazu ein Programm zum chuck-a-luck-Spiel. Hinweis: Tkinter steht für Toolkit-Interface und ist eine Bibliothek, die all die Programmeinheiten enthält, die man zur Erzeugung von Komponenten einer grafischen Benutzeroberfläche mit Python benötigt. Dieses Modul gehört zur Standarddistribution von Python und kann daher direkt genutzt werden.
22
Erzeugung eines Fensters
# -*- coding: iso *- from Tkinter import * # Erzeugung des Fensters tkFenster = Tk() tkFenster.title("chuck a luck") tkFenster.geometry('350x145') # Aktivierung des Fensters tkFenster.mainloop() Tk-Objekt
23
Anzeige von Text und Daten
# -*- coding: iso *- from Tkinter import * # Erzeugung des Fensters tkFenster = Tk() tkFenster.title("Test") tkFenster.geometry('120x110') # Label mit Überschrift für das Konto labelUeberschriftKonto = Label(master=tkFenster, \ text="Konto", \ background="#FFCFC9") labelUeberschriftKonto.place(x=10, y=10, width=100, height=20) # Label für den Kontostand labelKonto = Label(master=tkFenster) labelKonto.config(text="100") labelKonto.config(background="#FFCFC9") labelKonto.place(x=45, y=40, width=30, height=30) # Aktivierung des Fensters tkFenster.mainloop() Label-Objekt Label-Objekt
24
Anklicken von Schaltflächen
... # Ereignisverarbeitung def Button_Einsatz_Click(): # Verwaltung der Daten konto = int(labelKonto.cget('text')) # Verarbeitung der Daten konto = konto - 1 # Anzeige der Daten labelKonto.config(text=str(konto)) # Erzeugung des Fensters # Label für das Konto labelKonto = Label(master=tkFenster, \ text="100", \ background="#FFCFC9") labelKonto.place(x=45, y=35, width=30, height=30) # Button zum Auswerten buttonEinsatz = Button(master=tkFenster, \ text="Einsatz zahlen", \ command=Button_Einsatz_Click) buttonEinsatz.place(x=10, y=75, width=100, height=20) Ereignisverarbeitung Button-Objekt
25
Daten-verarbeitungs-muster
... # Ereignisverarbeitung def Button_Einsatz_Click(): # Schritt 1: Verwaltung der Daten konto = int(labelKonto.cget('text')) # Schritt 2: Verarbeitung der Daten konto = konto - 1 # Schritt 3: Anzeige der Daten labelKonto.config(text=str(konto)) # Erzeugung des Fensters # Label für das Konto labelKonto = Label(master=tkFenster, \ text="100", \ background="#FFCFC9") labelKonto.place(x=45, y=35, width=30, height=30) # Button zum Auswerten buttonEinsatz = Button(master=tkFenster, \ text="Einsatz zahlen", \ command=Button_Einsatz_Click) buttonEinsatz.place(x=10, y=75, width=100, height=20) Schritt 1: Erst werden die benötigten Daten von Attributen betreffender GUI-Objekte übernommen und in Hilfsvariablen zwischengespeichert. Beachte, dass hier oft Tyanpassungen erforderlich sind. Schritt 2: Die jetzt mit Hilfe von Variablen erfassten Daten werden mit Hilfe geeigneter Anweisungen verarbeitet. Schritt 3: Die Ergebnisse der Verarbeitung werden zur Anzeige auf dem Bildschirm an geeignete GUI-Objekte weitergegeben. Auch hier können Typumwandlungen erforderlich sein. Daten-verarbeitungs-muster Button-Objekt
26
Eingabe von Daten ... # Ereignisverarbeitung
def Button_Verdoppeln_Click(): # Verwaltung der Daten zahl = int(entryZahl.get()) # Verarbeitung der Daten zahl = zahl * 2 # Anzeige der Daten entryZahl.delete(0, END) entryZahl.insert(0, str(zahl)) # Erzeugung des Fensters # Eingabefeld für die Zahl entryZahl = Entry(master=tkFenster, \ background="white") entryZahl.place(x=45, y=35, width=30, height=30) # Button zum Auswerten buttonVerdoppeln = Button(master=tkFenster, \ text="Eingabe verdoppeln", \ command=Button_Verdoppeln_Click) Entry-Operationen Entry-Operationen Entry-Objekt
27
Gestaltung des Layout ... # Erzeugung des Fensters tkFenster = Tk()
tkFenster.title("Test") tkFenster.geometry('200x200') # Rahmen Konto frameKonto = Frame(master=tkFenster, background="#FFCFC9") frameKonto.place(x=30, y=40, width=110, height=100) # Label mit Überschrift für das Konto labelUeberschriftKonto = Label(master=frameKonto, text="Konto", background="white") labelUeberschriftKonto.place(x=5, y=5, width=100, height=20) # Label für den Kontostand labelKonto = Label(master=frameKonto, text="100", background="white") labelKonto.place(x=40, y=35, width=30, height=30) # Button zum Auswerten buttonEinsatz = Button(master=frameKonto, text="Einsatz zahlen", command=...) buttonEinsatz.place(x=5, y=75, width=100, height=20) # Aktivierung des Fensters tkFenster.mainloop() Frame-Objekt
28
Gestaltung des Layout ... Pixel-Koordinatensysteme
# Erzeugung des Fensters tkFenster = Tk() tkFenster.title("Test") tkFenster.geometry('200x200') # Rahmen Konto frameKonto = Frame(master=tkFenster, background="#FFCFC9") frameKonto.place(x=30, y=40, width=110, height=100) # Label mit Überschrift für das Konto labelUeberschriftKonto = Label(master=frameKonto, text="Konto", background="white") labelUeberschriftKonto.place(x=5, y=5, width=100, height=20) # Label für den Kontostand labelKonto = Label(master=frameKonto, text="100", background="white") labelKonto.place(x=40, y=35, width=30, height=30) # Button zum Auswerten buttonEinsatz = Button(master=frameKonto, text="Einsatz zahlen", command=...) buttonEinsatz.place(x=5, y=75, width=100, height=20) # Aktivierung des Fensters tkFenster.mainloop() Pixel-Koordinatensysteme Master-Slave-Hierarchie
29
Verarbeitung von Ereignissen
... # 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) labelWuerfelB.config(text=str(wuerfelB)) labelWuerfelC.config(text=str(wuerfelC)) Übergabe eines Event-Objekts ... # Label Würfel A labelWuerfelA = Label(master=frameWuerfel, \ text="1", \ background="white") labelWuerfelA.bind("<Double-Button-1>", wuerfelAWerfen) # Button zum Würfeln buttonWuerfel = Button(master=frameWuerfel, \ text="Wuerfel werfen") buttonWuerfel.bind("<Button-1>", alleWuerfelWerfen) Ereignis Ereignisverarbeitung Ereignis Ereignisverarbeitung
30
Auswahlmöglichkeit mit Radiobutton
... # Ereignisverarbeitung def Button_Auswahl_Click(): # Verwaltung der Daten zahl = spielzahl.get() # Anzeige der Daten labelAusgewaehlteZahl.config(text=str(zahl)) # Radiobutton für die Zahl spielzahl = IntVar() radiobutton1 = Radiobutton(master=frameZahl, text='1', value=1, variable=spielzahl) radiobutton1.place(x=5, y=30, width=30, height=18) radiobutton2 = Radiobutton(master=frameZahl, text='2', value=2, variable=spielzahl) radiobutton2.place(x=40, y=30, width=30, height=18) radiobutton3 = Radiobutton(master=frameZahl, text='3', value=3, variable=spielzahl) radiobutton3.place(x=75, y=30, width=30, height=18) # Label mit ausgewählter Zahl labelAusgewaehlteZahl = Label(master=frameZahl, text="", background="white") labelAusgewaehlteZahl.place(x=40, y=52, width=30, height=18) # Button zum Auswerten buttonAuswahl = Button(master=frameZahl, text="Auswahl anzeigen", \ command=Button_Auswahl_Click) IntVar-Objekt als Kontrollvariable Radiobutton-Objekt
31
Einbindung von Bildern
# -*- coding: iso *- from Tkinter import * # 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) # Bilder wuerfel1 = PhotoImage(file="w1.gif") # Label Würfel B labelWuerfelB = Label(master=frameWuerfel, image=wuerfel1) labelWuerfelB.place(x=40, y=35, width=30, height=30) # Aktivierung des Fensters tkFenster.mainloop() PhotoImage-Objekt
32
Einbindung von Bildern
... # Ereignisverarbeitung def Button_Wuerfel_Click(): # Verwaltung und Verarbeitung der Daten wuerfelB = randint(1,6) # Anzeige der Daten labelWuerfelB.config(text=str(wuerfelB)) if wuerfelB == 1: labelWuerfelB.config(image=wuerfel1) elif wuerfelB == 2: labelWuerfelB.config(image=wuerfel2) elif wuerfelB == 3: labelWuerfelB.config(image=wuerfel3) elif wuerfelB == 4: labelWuerfelB.config(image=wuerfel4) elif wuerfelB == 5: labelWuerfelB.config(image=wuerfel5) elif wuerfelB == 6: labelWuerfelB.config(image=wuerfel6) ... # Bilder wuerfel1 = PhotoImage(file="w1.gif") wuerfel2 = PhotoImage(file="w2.gif") wuerfel3 = PhotoImage(file="w3.gif") wuerfel4 = PhotoImage(file="w4.gif") wuerfel5 = PhotoImage(file="w5.gif") wuerfel6 = PhotoImage(file="w6.gif") # Label Würfel B labelWuerfelB = Label( \ master=frameWuerfel, image=wuerfel1) labelWuerfelB.place(...) # Button zum Würfeln buttonWuerfel = Button( \ master=frameWuerfel, \ text="Wuerfel werfen", \ command=Button_Wuerfel_Click)
33
Einbindung von Bildern
... # Ereignisverarbeitung def Button_Wuerfel_Click(): # Verwaltung und Verarbeitung der Daten wuerfelB = randint(1,6) # Anzeige der Daten labelWuerfelB.config(text=str(wuerfelB)) labelWuerfelB.config( \ image=wuerfelbilder[wuerfelB-1]) ... wuerfelbilder = [ \ PhotoImage(file="w1.gif"), \ PhotoImage(file="w2.gif"), \ PhotoImage(file="w3.gif"), \ PhotoImage(file="w4.gif"), \ PhotoImage(file="w5.gif"), \ PhotoImage(file="w6.gif") \ ] # Label Würfel B labelWuerfelB = Label( \ master=frameWuerfel, image=wuerfelbilder[0]) labelWuerfelB.place(...) # Button zum Würfeln buttonWuerfel = Button( \ command=Button_Wuerfel_Click)
34
Eine Leinwand für Grafiken
... # Ereignisverarbeitung def Button_Zeichnen_Click(): # Anzeige der Daten z = randint(0, 1) if z > 0: canvas.itemconfigure(id_pfeilnachoben, fill="black") canvas.itemconfigure(id_pfeilnachunten, fill="#FFCFC9") else: canvas.itemconfigure(id_pfeilnachoben, fill="#FFCFC9") canvas.itemconfigure(id_pfeilnachunten, fill="black") # Leinwand canvas = Canvas(master=tkFenster, background="#FFCFC9") canvas.place(x=5, y=5, width=110, height=100) id_pfeilnachunten = canvas.create_line(20, 40, 20, 60, arrow=LAST, fill="#FFCFC9") id_pfeilnachoben = canvas.create_line(90, 60, 90, 40, arrow=LAST, fill="#FFCFC9") # Button zum Zeichnen buttonZeichnen = Button(master=canvas, text="Zeichnen", \ command=Button_Zeichnen_Click) Canvas-Objekt
35
Animation mit einem Timer
... # Ereignisverarbeitung def Button_Zaehlen_Click(): # Verwaltung der Daten stand = int(entryZaehler.get()) if stand > 0: # Verarbeitung der Daten stand = stand - 1 # Anzeige der Daten entryZaehler.delete(0, END) entryZaehler.insert(0, str(stand)) # rekursiver Aufruf der Prozedur tkFenster.after(1000, Button_Zaehlen_Click) # Erzeugung des Fensters buttonZaehlen = Button(master=frameZaehler, \ text="Herunterzählen", \ command=Button_Zaehlen_Click) buttonZaehlen.place(x=5, y=75, width=100, height=20) after-Methode
36
Übungen (siehe ) Bearbeiten Sie die Aufgaben des Abschnitts
37
GUI-Objekte und Datenmodell-Objekte
Teil 4 GUI-Objekte und Datenmodell-Objekte
38
Exkurs - Datenhaltung m. GUI-Objekten
... # Ereignisverarbeitung def Button_Wuerfel_Click(): # Verwaltung und Verarbeitung der Daten wuerfelB = randint(1,6) # Anzeige der Daten labelWuerfelB.config(text=str(wuerfelB)) labelWuerfelB.config( \ image=wuerfelbilder[wuerfelB-1]) ... wuerfelbilder = [ \ PhotoImage(file="w1.gif"), \ PhotoImage(file="w2.gif"), \ PhotoImage(file="w3.gif"), \ PhotoImage(file="w4.gif"), \ PhotoImage(file="w5.gif"), \ PhotoImage(file="w6.gif") \ ] # Label Würfel B labelWuerfelB = Label( \ master=frameWuerfel, image=wuerfelbilder[0]) labelWuerfelB.place(...) # Button zum Würfeln buttonWuerfel = Button( \ command=Button_Wuerfel_Click) unbefriedigende Lösung: aktuelles Würfelergebnis wird hier zusätzlich als Zeichenkette abgespeichert
39
Exkurs - Datenhaltung m. globalen Var.
# -*- coding: iso *- from Tkinter import * from random import randint # Datenmodell konto = 100 wuerfelA = 1 wuerfelB = 1 wuerfelC = 1 zahl = None # Ereignisverarbeitung def Button_Einsatz_Click(): global konto # Verarbeitung der Daten konto = konto - 1 # Anzeige der Daten labelKonto.config(text=str(konto)) ... ... def Button_Wuerfel_Click(): global wuerfelA, wuerfelB, wuerfelC # Verwaltung und Verarbeitung der Daten wuerfelA = randint(1,6) wuerfelB = randint(1,6) wuerfelC = randint(1,6) # Anzeige der Daten if wuerfelA == 1: labelWuerfelA.config(image=wuerfel1) elif wuerfelA == 2: labelWuerfelA.config(image=wuerfel2) elif wuerfelA == 3: labelWuerfelA.config(image=wuerfel3) elif wuerfelA == 4: labelWuerfelA.config(image=wuerfel4) elif wuerfelA == 5: labelWuerfelA.config(image=wuerfel5) elif wuerfelA == 6: labelWuerfelA.config(image=wuerfel6) unbefriedigende Lösung: Spieldaten mit globalen Variablen verwalten
40
Exkurs - Datenmodell-Objekt
# -*- coding: iso *- from random import randint # Datenmodell class ChuckALuck(object): def __init__(self): self.konto = 100 self.spielzahl = 1 self.wuerfelA = 1 self.wuerfelB = 1 self.wuerfelC = 1 def einsatzZahlen(self): self.konto = self.konto - 1 def spielzahlSetzen(self, zahl): self.spielzahl = zahl ... ... def wuerfelWerfen(self): self.wuerfelA = randint(1,6) self.wuerfelB = randint(1,6) self.wuerfelC = randint(1,6) def gewinnAuszahlen(self): gewinn = 0 if self.spielzahl == self.wuerfelA: gewinn = gewinn + 1 if self.spielzahl == self.wuerfelB: if self.spielzahl == self.wuerfelC: if gewinn > 0: self.konto = self.konto + (gewinn + 1) Bauplan für ein Objekt zur Verwaltung der Spieldaten
41
Exkurs - Datenmodell-Objekt
# -*- coding: iso *- from random import randint # Datenmodell class ChuckALuck(object): def __init__(self): self.konto = 100 self.spielzahl = 1 self.wuerfelA = 1 self.wuerfelB = 1 self.wuerfelC = 1 def einsatzZahlen(self): ... def spielzahlSetzen(self, zahl): def wuerfelWerfen(self): def gewinnAuszahlen(self): >>> spiel = ChuckALuck() >>> spiel.konto 100 >>> spiel.einsatzZahlen() 99 >>> spiel.spielzahlSetzen(6) >>> spiel.spielzahl 6 >>> spiel.wuerfelWerfen() >>> spiel.wuerfelA 3 >>> spiel.wuerfelB >>> spiel.wuerfelC >>> spiel.gewinnAuszahlen() 102 Erzeugung und Nutzung des Datenmodell-Objekts Bauplan für ein Datenmodell-Objekt
42
Exkurs - Datenmodell- und GUI-Objekte
... # Datenmodell from chuckaluck_datenmodell import ChuckALuck spiel = ChuckALuck() # Ereignisverarbeitung def Button_Einsatz_Click(): # Verarbeitung der Daten spiel.einsatzZahlen() # Anzeige der Daten labelKonto.config(text=str(spiel.konto)) def Button_Wuerfel_Click(): spiel.wuerfelWerfen() labelWuerfelA.config(image=wuerfelbilder[spiel.wuerfelA-1]) def Button_Gewinn_Click(): spiel.spielzahlSetzen(spielzahl.get()) spiel.gewinnAuszahlen() Verarbeitung der Daten mit Datenmodell-Objekt Anzeige der Daten mit GUI-Objekt
43
Exkurs - verfeinertes Datenmodell
class ChuckALuck(object): def __init__(self): self.konto = 100 self.spielzahl = 1 self.wuerfelA = 1 self.wuerfelB = 1 self.wuerfelC = 1 self.zustand = "spielBeginnt" def einsatzZahlen(self): if self.zustand == "spielBeginnt": self.konto = self.konto - 1 self.zustand = "einsatzGezahlt" ... Zustandsdiagramm
44
Exkurs - verfeinertes Datenmodell
def Button_Einsatz_Click(): # Verarbeitung der Daten spiel.einsatzZahlen() # Anzeige der Daten labelKonto.config(text=str(spiel.konto)) def Button_Wuerfel_Click(): spiel.wuerfelWerfen() labelWuerfelA.config(image=wuerfelbilder[spiel.wuerfelA-1]) labelWuerfelB.config(image=wuerfelbilder[spiel.wuerfelB-1]) labelWuerfelC.config(image=wuerfelbilder[spiel.wuerfelC-1]) def Radiobutton_Click(): spiel.spielzahlSetzen(spielzahl.get()) def Button_Gewinn_Click(): spiel.gewinnAuszahlen() Zustandsdiagramm
45
Übungen Testen Sie die Datenmodell-Objekte wie gezeigt. Analysieren Sie auch das Zusammenspiel der Datenmodell- und GUI-Objekte.
46
GUI-Entwicklung mit Werkzeugen
Teil 5 GUI-Entwicklung mit Werkzeugen
47
Achtung: Tk_happy ist für den Einsatz im Unterricht wenig geeignet.
GUI-Builder Ein GUI-Builder ist ein Werkzeug, das den Benutzer bei der Entwicklung einer Benutzeroberfläche unterstützt. Der Benutzer kann mit einfachen Maus-Operationen die gewünschte Benutzeroberfläche erstellen, das Werkzeug erzeugt den zugehörigen Quelltext. Es gibt eine ganze Reihe von GUI-Buildern, die die Erstellung einer Benutzeroberfläche unter Python unterstützen. Aber nur wenige erzeugen einen einfach zu durchschauenden Quelltext, der zusätzlich noch mit dem hier eingeschlagenen Weg kompatibel ist. Tk_happy ist ein GUI-Builder für Python, der das Modul Tkinter benutzt. Auf der Projekthomepage von Tk_happy wird dieser GUI-Builder so beschrieben: "The main idea behind tk_happy is to allow a fully "wired" python Tkinter GUI application to be created in minutes. The users main responsibility is to add logic to the Tkinter framework created by tk_happy." Achtung: Tk_happy ist für den Einsatz im Unterricht wenig geeignet.
48
Beispiel - Simulation eines Würfels
Die folgende grafische Benutzeroberfläche soll - ohne das Werkzeug Tk_happy - mit dem Werkzeug Tk_happy erstellt werden.
49
Vorbereitung - GUI-Objekte
... def Button_Wuerfeln_Click(event): from random import randint # Verarbeitung der Daten augen = randint(1, 6) # Anzeige der Daten labelWuerfel.config(text=int(augen)) # Erzeugung des Fensters fenster = Tk() fenster.title("Würfeln") fenster.geometry('300x200') # Rahmen für die Benutzungsoberfläche rahmen = Frame(master=fenster, background="white") rahmen.place(x=0, y=0, width=300, height=200) # Label für das Würfelergebnis labelWuerfel = Label(master=rahmen, background="blue", foreground="white", text="1") labelWuerfel.place(x=138, y=72, width=24, height=24) # Button Wuerfeln buttonWuerfeln = Button(master=rahmen, text="würfeln") buttonWuerfeln.bind("<ButtonRelease-1>", Button_Wuerfeln_Click) buttonWuerfeln.place(x=100, y=150, width=101, height=25) # Aktivierung des Fensters fenster.mainloop() Erzeugung der GUI-Objekte
50
Vorbereitung - GUI-Klasse
... class Wuerfel(object): def __init__(self): # Label für das Würfelergebnis self.labelWuerfel = Label(master=self.rahmen, background="blue", ...) self.labelWuerfel.place(x=138, y=72, width=24, height=24) # Button Wuerfeln self.buttonWuerfeln = Button(master=self.rahmen, text="würfeln") self.buttonWuerfeln.bind("<ButtonRelease-1>", self.Button_Wuerfeln_Click) self.buttonWuerfeln.place(x=100, y=150, width=101, height=25) # Aktivierung des Fensters self.fenster.mainloop() def Button_Wuerfeln_Click(self, event): from random import randint # Verarbeitung der Daten augen = randint(1, 6) # Anzeige der Daten self.labelWuerfel.config(text=int(augen)) # Erzeugung des GUI-Objekts wuerfelGUI = Wuerfel() Definition einer GUI-Klasse Objekt zur Verwaltung der GUI-Objekte
51
Vorbereitung - GUI-Klasse
... class Wuerfel(object): def __init__(self, master): self.master = master self.rahmen = Frame(master=self.master, background="white") # Label für das Würfelergebnis self.labelWuerfel = Label(master=self.rahmen, background="blue", ...) # Button Wuerfeln self.buttonWuerfeln = Button(master=self.rahmen, text="würfeln") self.buttonWuerfeln.bind("<ButtonRelease-1>", self.Button_Wuerfeln_Click) def Button_Wuerfeln_Click(self, event): from random import randint augen = randint(1, 6) self.labelWuerfel.config(text=int(augen)) # Erzeugung der Objekte fenster = Tk() fenster.title("Würfeln") fenster.geometry('300x200') wuerfelGUI = Wuerfel(fenster) fenster.mainloop() Definition einer GUI-Klasse Objekt zur Verwaltung der GUI-Objekte
52
Exkurs - Tk_happy Das Werkzeug Tk_happy stellt dem Benutzer drei Fenster zur Verfügung. Formular-Fenster Menu-Fenster Objekt-Inspektor
53
von Tk_happy erzeugter Quelltext
Exkurs - Tk_happy ... class _Wuerfel: def __init__(self, master): self.master.title("Wuerfel") self.Button_Wuerfeln = Button(self.master,text="wuerfeln", \ background="SystemButtonFace", width="15") self.Button_Wuerfeln.place(x=100, y=150, width=101, height=25) self.Button_Wuerfeln.bind("<ButtonRelease-1>", self.Button_Wuerfeln_Click) self.Label_Wuerfel = Label(self.master,text="6", foreground="white", \ background="blue", width="15") self.Label_Wuerfel.place(x=138, y=72, width=24, height=24) def Button_Wuerfeln_Click(self, event): #click method for component ID=1 pass def main(): root = Tk() app = _Wuerfel(root) root.mainloop() if __name__ == '__main__': main() von Tk_happy erzeugter Quelltext
54
Exkurs - Tk_happy ... class _Wuerfel: def __init__(self, master):
self.master.title("Wuerfel") self.Button_Wuerfeln = Button(self.master,text="wuerfeln", \ background="SystemButtonFace", width="15") self.Button_Wuerfeln.place(x=100, y=150, width=101, height=25) self.Button_Wuerfeln.bind("<ButtonRelease-1>", self.Button_Wuerfeln_Click) self.Label_Wuerfel = Label(self.master,text="6", foreground="white", \ background="blue", width="15") self.Label_Wuerfel.place(x=138, y=72, width=24, height=24) def Button_Wuerfeln_Click(self, event): #click method for component ID=1 from random import randint # Verarbeitung der Daten augen = randint(1, 6) # Anzeige der Daten self.Label_Wuerfel.config(text=int(augen)) ergänzter Quelltext
55
Exkurs - PythonCard PythonCard ist ein Werkzeug zur Entwicklung grafischer Benutzeroberflächen für Python-Programme. Auf der Projekthomepage von PythonCard wird dieser GUI-Builder so beschrieben: "PythonCard is a GUI construction kit for building cross-platform desktop applications on Windows, Mac OS X, and Linux, using the Python language. The PythonCard motto is "Simple things should be simple and complex things should be possible." PythonCard is for you if you want to develop graphical applications quickly and easily with a minimum of effort and coding." PythonCard benutzt wxPython. Wenn du PythonCard benutzen willst, dann musst du sowohl wxPython als auch PythonCard installieren. Für weitere Informationen siehe
56
Teil 6 Miniprojekte
57
Vorgehensweise Schritt 1: Entwurf zur Benutzeroberfläche
Überlege dir zunächst, was die Benutzeroberfläche alles leisten soll: In welcher Weise soll sie den Benutzer informieren? In welcher Weise soll der Benutzer selbst agieren können? Entwickle (am besten auf Papier) einen ersten Entwurf für eine Benutzersoberfläche, die das Gewünschte leistet. Schritt 2: Struktur der Benutzeroberfläche Erzeuge mit Hilfe geeigneter Komponenten eine Benutzeroberfläche, die den Entwurf umsetzt. Lass zunächst alle Details der Prozeduren, die bei bestimmten Ereignissen ausgeführt werden sollen, weg. Das Programm sollte lauffähig sein, aber noch nicht in der gewünschten Weise beim Eintreten der jeweiligen Ereignisse reagieren. Schritt 3: Dynamik der Benutzeroberfläche Bei etwas komplexeren Programmen solltest du zunächst ein eigenständiges Datenmodell entwickeln und unabhängig von der Benutzeroberfläche testen. Implementiere jetzt die Prozeduren zur Ereignisbearbeitung. Teste alle Funktionalitäten des Programms Mach das Programm möglichst fehlertolerant. Schritt 4: Layout der Benutzeroberfläche Zum Abschluss kannst du das Layout der Benutzeroberfläche nochmal überarbeiten und nach deinen Wünschen gestalten.
58
Miniprojekt - Ziegenproblem
Weißt du, worum es beim Ziegenproblem geht? Wenn nicht, dann lies dir die Problemstellung bei Wikipedia durch. Mit Hilfe eines Simulationsprogramms soll herausgefunden werden, ob es für den Kandidaten günstiger ist, bei seiner ersten Wahl zu bleiben, oder umzuwählen. Entwickle ein Programm zur Simulation des Ziegenproblemspiels. Über eine grafische Benutzeroberfläche soll der Spieler / die Spielerin die Spielaktionen des Kandidaten durchführen können. Die Aktionen des Moderators sollen vom Programm übernommen werden. Das Programm soll selbstbeschreibend und fehlertolerant gestaltet werden. Orientiere dich bei der Entwicklung an den im letzten Abschnitt aufgezeigten Schritten.
59
Miniprojekt - Taschenrechner
Der Taschenrechner soll folgendermaßen funktionieren: Der Benutzer / die Benutzerin kann einfache Rechenaufgaben wie z. B. 342*28= mit geeigneten Schaltflächen (die den Tasten entsprechen) eintippen. Mit einer bestimmten Schaltfläche kann man den Taschenrechner aktivieren, die Rechnung durchzuführen und das Ergebnis im Display anzuzeigen. Es soll ein Programm zur Simulation eines Taschenrechners entwickelt werden. Über eine grafische Benutzeroberfläche soll der Benutzer / die Benutzerin die Aktionen ausführen können. Das Programm soll selbstbeschreibend und fehlertolerant gestaltet werden. Orientiere dich bei der Entwicklung an den im letzten Abschnitt aufgezeigten Schritten.
Ähnliche Präsentationen
© 2025 SlidePlayer.org Inc.
All rights reserved.