Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Grafische Benutzeroberflächen Klaus Becker 2009. 2 Grafische Benutzeroberflächen Inhalte: Benutzerfreundlichkeit Aufbau und Verhalten GUI-Entwicklung.

Ähnliche Präsentationen


Präsentation zum Thema: "Grafische Benutzeroberflächen Klaus Becker 2009. 2 Grafische Benutzeroberflächen Inhalte: Benutzerfreundlichkeit Aufbau und Verhalten GUI-Entwicklung."—  Präsentation transkript:

1 Grafische Benutzeroberflächen Klaus Becker 2009

2 2 Grafische Benutzeroberflächen Inhalte: Benutzerfreundlichkeit Aufbau und Verhalten GUI-Entwicklung (mit Tkinter) GUI-Objekte und Datenmodell-Objekte GUI-Entwicklung mit Werkzeugen

3 3 Teil 1 Benutzerfreundlichkeit

4 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 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 6 Übungen (siehe ) Beurteilen Sie die im Einstieg gezeigten Programme hinsichtlich der Kriterien für Benutzerfreundlichkeit.

7 7 Teil 2 Aufbau und Verhalten

8 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)... G(raphical) U(ser) I(interface) Auszug aus dem Quelltext

9 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 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 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 12 Fachkonzept - GUI-Objekt... # 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="")... objektname = GUIKlasse(...) Erzeugung eines GUI-Objekts

13 13 Fachkonzept - GUI-Objekt... # Label für die Überschrift labelUeberschrift = Label(master=frameUeberschrift, \ background="white", \ text="Anhalteweg eines Autos")... 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. AttributwerteAttribute

14 14 Fachkonzept - GUI-Objekt 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) Zur Verarbeitung der verwalteten Daten stellen Objekte Operationen (man sagt auch Methoden) bereit. OperationObjekt objektname.operation Aktivierung einer Operation

15 15 Fachkonzept - Ereignissteuerung def Button_Berechnen_Click():... # Erzeugung des Fensters tkFenster = Tk()... buttonBerechnen = Button(master=frameVerarbeitung, \ text="berechnen", \ command=Button_Berechnen_Click)... # Aktivierung des Fensters tkFenster.mainloop() 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. Aktierung der Ereignisschleife Ereignisverarbeitungsprozedur wiederhole: wenn ein Ereignis eintritt: führe die zugeordneten Prozedur zur Ereignisverarbeitung aus Ereignisschleife

16 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 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: [Anweisungen]

18 18 Übungen (siehe ) Bearbeiten Sie die Aufgaben des Abschnitts

19 19 Teil 3 Entwicklung

20 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 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 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 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

24 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 25 Datenverarbeitung... # 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)... Daten- verarbeitungs- muster Button-Objekt 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.

26 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-Objekt Entry-Operationen

27 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 28 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() Master-Slave- Hierarchie Pixel- Koordinatensysteme

29 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) # Anzeige der Daten labelWuerfelA.config(text=str(wuerfelA)) labelWuerfelB.config(text=str(wuerfelB)) labelWuerfelC.config(text=str(wuerfelC))... # Label Würfel A labelWuerfelA = Label(master=frameWuerfel, \ text="1", \ background="white") labelWuerfelA.bind(" ", wuerfelAWerfen)... # Button zum Würfeln buttonWuerfel = Button(master=frameWuerfel, \ text="Wuerfel werfen") buttonWuerfel.bind(" ", alleWuerfelWerfen)... EreignisEreignisverarbeitung EreignisEreignisverarbeitung Übergabe eines Event-Objekts

30 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)... Radiobutton-Objekt IntVar-Objekt als Kontrollvariable

31 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 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 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 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 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 36 Übungen (siehe ) Bearbeiten Sie die Aufgaben des Abschnitts

37 37 Teil 4 GUI-Objekte und Datenmodell-Objekte

38 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 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 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: gewinn = gewinn + 1 if self.spielzahl == self.wuerfelC: gewinn = gewinn + 1 if gewinn > 0: self.konto = self.konto + (gewinn + 1) Bauplan für ein Objekt zur Verwaltung der Spieldaten

41 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() >>> spiel.konto 99 >>> spiel.spielzahlSetzen(6) >>> spiel.spielzahl 6 >>> spiel.wuerfelWerfen() >>> spiel.wuerfelA 3 >>> spiel.wuerfelB 6 >>> spiel.wuerfelC 6 >>> spiel.gewinnAuszahlen() >>> spiel.konto 102 Bauplan für ein Datenmodell-Objekt Erzeugung und Nutzung des Datenmodell-Objekts

42 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(): # Verarbeitung der Daten spiel.wuerfelWerfen() # Anzeige der Daten labelWuerfelA.config(image=wuerfelbilder[spiel.wuerfelA-1])... def Button_Gewinn_Click(): # Verarbeitung der Daten spiel.spielzahlSetzen(spielzahl.get()) spiel.gewinnAuszahlen() # Anzeige der Daten labelKonto.config(text=str(spiel.konto))... Verarbeitung der Daten mit Datenmodell-Objekt Anzeige der Daten mit GUI-Objekt

43 43 Exkurs - verfeinertes Datenmodell # 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 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(): # Verarbeitung der Daten spiel.wuerfelWerfen() # Anzeige der Daten labelWuerfelA.config(image=wuerfelbilder[spiel.wuerfelA-1]) labelWuerfelB.config(image=wuerfelbilder[spiel.wuerfelB-1]) labelWuerfelC.config(image=wuerfelbilder[spiel.wuerfelC-1]) def Radiobutton_Click(): # Verarbeitung der Daten spiel.spielzahlSetzen(spielzahl.get()) def Button_Gewinn_Click(): # Verarbeitung der Daten spiel.gewinnAuszahlen() # Anzeige der Daten labelKonto.config(text=str(spiel.konto)) Zustandsdiagramm

45 45 Übungen Testen Sie die Datenmodell-Objekte wie gezeigt. Analysieren Sie auch das Zusammenspiel der Datenmodell- und GUI-Objekte.

46 46 Teil 5 GUI-Entwicklung mit Werkzeugen

47 47 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 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 49... 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(" ", Button_Wuerfeln_Click) buttonWuerfeln.place(x=100, y=150, width=101, height=25) # Aktivierung des Fensters fenster.mainloop() Vorbereitung - GUI-Objekte Erzeugung der GUI-Objekte

50 50... 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(" ", 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() Vorbereitung - GUI-Klasse Objekt zur Verwaltung der GUI-Objekte Definition einer GUI-Klasse

51 51... 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(" ", 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() Vorbereitung - GUI-Klasse Definition einer GUI-Klasse Objekt zur Verwaltung der GUI-Objekte

52 52 Exkurs - Tk_happy Das Werkzeug Tk_happy stellt dem Benutzer drei Fenster zur Verfügung. Menu-Fenster Formular-Fenster Objekt-Inspektor

53 53... 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(" ", 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() Exkurs - Tk_happy von Tk_happy erzeugter Quelltext

54 54... 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(" ", 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))... Exkurs - Tk_happy ergänzter Quelltext

55 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 56 Teil 6 Miniprojekte

57 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 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 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.


Herunterladen ppt "Grafische Benutzeroberflächen Klaus Becker 2009. 2 Grafische Benutzeroberflächen Inhalte: Benutzerfreundlichkeit Aufbau und Verhalten GUI-Entwicklung."

Ähnliche Präsentationen


Google-Anzeigen