Erste Programme mit Lazarus Einführung in die Entwicklungsumgebung (IDE) Grundelemente der Programmiersprache Objekt-Pascal Übungen Helmut Paulus Speyer, 19.04.13 Teil 1 Einführung in die Lazarus-Entwicklungsumgebung Grundelemente der Programmiersprache Objekt-Pascal Was ist Lazarus 3 Lazarus ist eine plattformunabhängige freie, Delphi-ähnliche Entwicklungsumgebung für die Programmiersprache Objekt Pascal - eine Bezeichnung für mehrere ProgrammiersprachenVarianten, die Pascal um Objektorientierte Programmierung erweitern, am bekanntesten davon ist die Programmiersprache der Entwicklungsumgebung Embarcadero Delphi, die Delphi genannt wurde. baut auf dem Free Pascal Compiler (FPC) auf, seine Komponentenbibliothek (LCL) ist sehr ähnlich zu der von Delphi (VCL), ist daher höchst kompatibel zu Delphi. Lazarus-Projekt: http://www.lazarus.freepascal.org/ Beschreibungen bei Wikipedia: Lazarus: http://de.wikipedia.org/wiki/Lazarus_(Entwicklungsumgebung) Objekt Pascal: http://de.wikipedia.org/wiki/Object_Pascal 4 Entwicklungsumgebung (IDE) Komponenten-Palette Formular (GUI) Objektinspektor Quelltextfenster Lazarus-Projekt 5 Lazarus erzeugt eine ganze Reihe von Dateien zur Verwaltung eines Programmierprojektes. Diese Dateien sollte man immer in einem eigenen Ordner speichern. (Quellcodedateien werden als Units bezeichnet.) Vorbereitende Schritte: 1. Ordner für das neue Projekt anlegen 2. Neues Projekt anlegen: Datei->Neu->Anwendung 3. Projektdateien sofort speichern: (1) Datei - Alles speichern (2) die vom System vorgeschlagen Namen unit1.pas und project1.lpr umbenennen (z. B.: ugui.pas und Rechner.lpr) u – für Unit (Quelltextdatei) Neben den oben genannten beiden Dateien werden automatisch im Projektordner viele weitere Dateien angelegt und laufend von Lazarus verwaltet und aktualisiert. Beim Kompilieren wird aus den Projektdateien ein lauffähiges Programm Rechner.exe erzeugt, das anschließend ausgeführt werden kann. 6 Projektaufbau Ein Projekt besteht einzelnen Units, die einer Projektdatei verwaltet werden. Projekt Rechner 7 Speichern Sie den Ordner Rechner in ein eigenes Verzeichnis. Laden und starten Sie dann das Projekt in Lazarus und testen Sie seine Funktionalität. Analysieren Sie den Quelltext. Führen Sie auf dem Formular einen Doppelklick auf ein Button-Objekt aus. Was passiert? Fügen Sie einen weiteren Button hinzu. Lassen Sie sich über Projekt und .lpr Datei anzeigen den Quelltext der Projektdatei anzeigen. Was geschieht dort? Klicken Sie mit rechten Maustaste ins Formular und öffnen Sie mit Quelltext (.lfm) anzeigen die Formulardatei. Analysieren Sie den Inhalt. 8 Entwicklung der GUI Formular im Entwurfsmodus PAnzeige : TPanel Label1 : TLabel EErgebnis: TEdit form1 : TForm1 (Formular) Bplus : TButton GUI-Objekte (Komponenten der Komponentenpalette) werden auf dem Formular platziert und mit Hilfe des Objektinspektors (Register Eigenschaften) editiert. GUI-Objekte haben einen Namen und gehören ein Klasse an. Komponenten 9 Das Formular enthält Komponenten (GUI-Objekte) vom Typ: • TForm, TEdit, TButton, TLabel, TPanel Sinnvolle Namenskonvention Der Editor gibt den GUI-Objekten automatisch Namen, z. B. TForm1, Label1, Button1, Button2 Die Objekte sollten im Objektinspektor mit sinnvollen Namen (nach Konventionen) belegt werden; z. B.: je nach Typ des Objekts einen Präfix: Name Funktionalität Bplus B für Button Schaltfläche EZahl1 E für Edit Text-Eingabefeld einzeilig PHinweis P für Panel Container für Komponenten Lergebnis L für Label Beschriftungsfeld Standardattribute (Eigenschaften) der GUI-Objekte: • Caption Beschriftung einer Komponente (Aufschrift eines Buttons, Labels, Panels,…) • Text Inhalt eines Textfeldes (Edit) • Name Name, mit dem das Objekt im Programm angesprochen wird Objekthierarchie 10 Das Formularobjekt Form1 verwaltet alle anderen Objekte als Unterobjekte. Die zur Entwurfszeit definierten Attributwerte werden in der so genannten Formulardatei ugui.lfm gespeichert. Die Formulardatei wird automatisch erzeugt und gepflegt und hat immer den gleichen Namen wie die Quelltextdatei ugui.pas. object Form1: TForm1 Left = 354 Height = 176 Top = 248 Width = 229 Caption = 'Rechner' ClientHeight = 176 ClientWidth = 229 LCLVersion = '1.0.8.0‚ ... object EZahl1: TEdit Left = 8 Height = 23 Top = 64 Width = 90 TabOrder = 0 end object Bplus: TButton Left = 32 Height = 25 Top = 136 Width = 25 Caption = '+' OnClick = BplusClick TabOrder = 2 end end Quelltext-Interface 11 unit ugui; {$mode objfpc}{$H+} Unit-Name - beim Speichern vom System geschrieben interface uses Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls; type { TForm1 } TForm1 = class(TForm) Bplus: TButton; EZahl1: TEdit; EErgebnis: TEdit; Label2: TLabel; Label4: TLabel; Panel1: TPanel; procedure BplusClick(Sender: TObject); private { private declarations } public { public declarations } end; var Form1: TForm1; ... end. Einbinden von Systemunits (automatisch) Formularklasse TForm1 Basisklasse: Tform (automatisch) Attribute Ereignismethoden Variablendeklaration (Formularobjekt) Quelltext-Implementation 12 unit ugui; ... var Form1: TForm1; implementation *.lfm Formulardatei einbinden (automatisch) {$R *.lfm} Ereignisbearbeitung { TForm1 } procedure TForm1.BplusClick(Sender: TObject); var z1: Extended; z2: Extended; sum: Extended; begin // Eingabe der Daten aus GUI-Objekten z1 := StrToFloat(EZahl1.Text); z2 := StrToFloat(EZahl2.Text); //Verarbeitung sum := z1 + z2; //Ausgabe EErgebnis.Text := FloatToStr(sum); end; end. Zugriff auf Attribute der GUI-Objekte 13 Projektverwaltung Ein Lazarus-Projekt besteht im aus mehreren Dateien, die im einfachsten Fall alle im gleichen "Projekt-Ordner" liegen. Die Verbindung wird durch die Projekt-Datei *.lpr hergestellt. program Rechner; {$mode objfpc}{$H+} uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} Interfaces, // this includes the LCL widgetset Forms, ugui { you can add units after this }; {$R *.res} begin RequireDerivedFormResource := True; Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end. Diese Datei wird automatisch vom System gepflegt! Hier findet sich u. a. die Einbindung von Units und Ressourcen die Erzeugung des Fensterobjektes den Start des Programms (Hauptprogramm) Überblick: Dateien des Projekts 14 Dateien des Projektordners (zum Teil automatisch angelegt) Bedeutung: Datei Inhalt *.pas Pascal-Quellcode Datei (Unit) *.lfm Lazarus Formulardatei – wird zu jeder Unit, in der ein Formularobjekt definiert ist, automatisch angelegt, enthält die Formulareinstellungen einschließlich aller Komponenten *.lpr (Lazarus Projektdatei) - das Hauptmodul (Verwaltung) des Projektes *.exe Das lauffähige Programm, zur Benutzung ist nur diese „EXE-Datei“ erforderlich *.lpi Lazarus Project Information - alle wichtigen Informationen des Lazarus-Projektes im XML-Format *.lrs Resourcendatei des Lazarus-Projektes *.ppu Compilierter Code der einer Unit, wird mit der Uses-Anweisung im Quellprogramm eingebunden Ereignisverarbeitung 15 Ereignisse werden in Object Pascal mit Hilfe von Methodenzeigern realisiert, das sind Attribute, die Referenzen auf Methoden anderer Objekte enthalten (Callback). Durch Doppelklick auf den Button Bplus wird eine Ereignismethode erzeugt und dem Methodenzeiger OnClick des Buttonobjekts zugewiesen. Sie ist eine Methode des Formularobjekts und wird vom Buttonobjekt durch Click ausgelöst. Ereignismethode des OnClick - Ereignisses procedure TForm1.BplusClick(Sender: TObject); begin ... end; • • Der vom System gebildete Name enthält die Namen der auslösenden Komponente und des Methodenzeigers als Bestandteile. Der vorangestellte Klassenname TForm1 bindet die Prozedur an das Formularobjekt. Die Ereignisse des Button-Objekts sind Methodenzeiger, die mit Ereignismethoden verknüpft werden können. Ereignisverarbeitung 16 Implementierung procedure TForm1.BplusClick(Sender: TObject); Var z1, z2, z3, sum: double; begin Deklaration der lokalen Variablen // Einlesen der Daten aus GUI-Objekten z1:= StrToFloat(EZahl1.Text); z2:= StrToFloat(EZahl2.Text); //Verarbeitung sum := z1 + z2; //Ausgabe EErgebnis.Text := FloatToStr(sum); end; Ein-/ Ausgabesystem mit lokalen Variablen als temporären Zwischenspeichern! Hilfesystem 17 Kontextsensitive Hilfe mit F1 LCL - Lazarus Component Library FCL - Free Component Library RTL - Runtime Library Laufzeit Debugger Haltepunkte im Quelltext setzen, an Stellen, wo das Programm halten soll, in den Rahmen neben der Quelltextzeile klicken ab dieser Stelle können die Anweisungen schrittweise ausgeführt und mit Hilfe der Maus der Wert der Variablen angezeigt werden Einzelschritt Standardkomponenten 18 Klasse Beschreibung Wichtige Eigenschaften/ Methoden TButton Schaltfläche Caption, Color, Font, Enabled FLabel Anzeige von Text Caption, Color, Font Edit Einzeiliges Eingabefeld Text, Color, Font, MaxLength, Clear TMemo Mehrzeiliges Eingabefeld Text, Lines, Append, Clear TListBox Auswahlliste mit mehreren Textzeilen ein Items, Append, Clear TGroupBox Rahmen zur Anordnung von Objekten mit Caption, Color, Font Gruppenbezeichnung. TPanel Rahmen zur Anordnung von Objekten Caption, Color, Font TImage Anzeige von Grafiken Picture, Canvas, loadfromfile TShape Grafische Form Brush, Pen, Shape 19 Teil 2 Grundelemente Objekt-Pascal Einstieg 20 Variablendeklaration Bezeichner Wertzuweisung Kommentar procedure TForm1.BplusClick(Sender: TObject); var z1,z2, Datentyp z3, sum : double; begin // Einlesen der Daten aus GUI-Objekten z1 := StrToFloat(EZahl1.Text); Trennzeichen z2 := StrToFloat(EZahl2.Text); Anweisungen //Verarbeitung sum := z1 / z2; //Ausgabe EErgebnis.Text:=FloatToStrF(sum,ffFixed,0,2); end; string Variablendeklaration var Bezeichner : Datentyp; Typumwandlung double Wertzuweisung a := b ; Die Variablen müssen zuweisungskompatibel sein! Grundelemente 21 Konventionen für Bezeichner Es dürfen nur folgende Zeichen verwendet werden Buchstaben (aber keine Umlaute) Zahlen, diese aber erst nach mindestens einem Buchstaben Unterstrich (auch am Anfang) ansonsten keine Sonderzeichen wie „,“, „;“ … Objekt-Pascal ist nicht kontextsensitiv! Blöcke und Kommentare Gleichheitszeichen Wertzuweisungen := Beispiel: x := x + 1; Vergleich: = Anweisungsblöcke begin … end; Kommentare //…. Bis Zeilenende { … } mehrzeilig Variablen und Konstanten 22 Delphi-Variablen sind Platzhalter (Container) für Daten. Diese werden im Computer durch einen Speicherbereich repräsentiert und mit Hilfe eines Namens angesprochen. Variablen haben einen Namen, einen Datentyp, einen Gültigkeitsbereich und eine Lebensdauer. Bevor eine Variable benutzt werden kann, muss sie deklariert werden. Dabei werden der Name und der Datentyp festgelegt. Gleichzeitig wird ein Speicherbereich für den speziellen Datentyp reserviert. Bei Wertzuweisungen muss die Zuweisungs-Kompatibiliät gewährleistet sein. Variablendeklaration Konstanten Programmabschnitt: var Syntax: const Bezeichner= wert; Syntax: var Bezeichner : Datentyp; Beispiel: const pi = 3.14; Beispiel: var Konstanten haben einen unveränderlichen Wert. anzahl : integer; z1, z1 : double; Elementare Datentypen 23 Einfache Datentypen integer : Ganze Zahlen {17, -12} double : Fließkommazahlen {2.675. 1.5e-10} boolean : Wahrheitswerte {true, false} string : Zeichenkette {‘Hallo‘} Char : ASCII-Zeichen {‘A‘, #65, chr(65)} Aufzählungstypen (ordinale Typen) Statt Zahlen konstante Bezeichner verwenden: var farben : (blau, gelb, gruen, rot); Die Typen Integer und Char gehören ebenfalls zu den ordinalen Typen. Arrays / Reihungen (statisch) var Bezeichner : array[StartInd..EndInd] of Datentyp; So definierte Array ist statisch, die Anzahl der Elemente kann nicht mehr verändert werden. Start- und Endindex vom Typ Integer oder Aufzählungstyp Datentyp muss ein einfacher Typ sein! Typumwandlungen 24 Bei der Ein- und Ausgabe von Daten mit Hilfe von GUI-Objekten müssen häufig Datentypen konvertiert werden. Objekt-Pascal Funktionen: Funktion : Ergebnistyp Beispiel StrToInt(Para) : integer groesse := StrToInt(EGroesse.Text); IntToStr(Para) : string PAusgabe.Caption := FloatToStr(BMI); StrToFloat(Para) : real FloatToStr(Para) : string Formatierte Ausgabe: Siehe Kontexthilfe FloatToStrF() : string PAusgabe.Caption := FloatToStrF(BMI, ffnumber, 8, 2); Char – ASCII-Zeichen Chr(0..255) : Char Ch := Chr(65); Ord(ch) : integer code := Ord(‘A‘); Operatoren 25 Arbeiten mit Zeichenketten Zeichenkettentexte werden in einfachen Anführungszeichen geschrieben. Beispiel: var Ausgabe : string; Ausgabe := ‘Du hast ‘; Zeichenketten kann man mit ‚+‘ aneinander hängen. Ausgabe := Ausgabe + ‘leider verloren‘; Die Länge einer Zeichenkette bestimmt man mit der System-Funktion „length()“. Zugriff auf die einzelnen Zeichen einer Zeichenkette über den Index Ausgabe[2] ‘u‘ Arithmetische Operatoren integer / real +, -, *, / Division ( liefert einen Realtyp bei Anwendung auf Integer z. B. 12/4) integer div mod Ganzzahldivision Beispiel: 7 div 5 1 Modulo Beispiel: 4 mod 3 1 Operatoren 26 Logische Operatoren AND true : wenn beide Operanden wahr OR true : wenn einer oder beide Operanden wahr NOT Negation des Operanden ( NOT a) Vergleichsoperatoren = <> < <= > Beispiel: var >= x : integer; teilbar : boolean; teilbar := (x mod 3 = 0) AND (x mod 5 = 0); Funktionen zum Arbeiten mit Aufzählungstypen Ord() gibt die Position des Bezeichners zurück Pred() gibt den Vorgänger zurück Succ() gibt den Nachfolger zurück Low() gibt den niedrigsten Wert zurück High() gibt den höchsten Wert zurück gleich ungleich Kleiner kleiner gleich Größer größer gleich Laufzeitfehler 27 Laufzeitfehler abfangen mit einem try-except Block Syntax Beispiel: try try Anweisungen z := StrToInt(Ezahl.Text); Except Except Fehlerbehandlung ShowMessage(‘Falsche Eingabe!‘); end; Im except - Abschnitt kann die Art des Fehlers (der Exception) geprüft und individuell bearbeitet werden. end; except on EZeroDivide do ...; on EMathError do ...; on EConvertError do ...; else ...; end; Fallunterscheidungen 28 If … then … else Case … of Einseitig Mehrfachverzweigung If Ausdruck then begin Anweisung; end; case 1 : 2 : 3 : else end; zweiseitig If Bedingung then begin Anweisung; end else begin Anweisung; end; kein Semikolon vor else OrdWert of ... ; ... ; ... ; ... ; Schleifen 29 Anfangsbedingung Zählschleife while Schleife For –Schleife while Bedingung do begin Anweisung; end; for i := 1 to n do begin Anweisung; end; Endbedingung Schleifen über Arrays: Repeat – Schleife var augen : array[1..6] of integer; repeat Anweisung; until Bedingung; for i := 1 to 6 do augen[i] := i; Prozeduren und Funktionen 30 Prozeduren procedure Bezeichner(Parameter); var lokale Variablen; Deklarationsteil Die Parameterliste kann auch fehlen begin Anweisungen; end; Anweisungsteil Funktionen Das Ergebnis muss einen einfachen Datentyp besitzen. function Bezeichner(Parameter): Datentyp; Rückgabentyp var lokale Variablen; begin Anweisung; result := Ergebnis; Rückgabewert end; Das Funktionsergebnis wird der Funkionsvariablen result zugewiesen. Methoden 31 Prozeduren und Funktionen als Methoden Bei Methoden steht vor dem Methodennamen der Name der Bezugsklasse setzt. Beispiel: Die Funktion Max als Funktion des Formular-Objekts vom Typ TForm1 TForm1 = class(TForm) private { Private-Deklarationen} Deklaration der Funktion function Max(z1, z2 : integer): integer; als private Methode von TForm1 public { Public-Deklarationen} end; function TForm1.Max(z1,z2: integer): integer; begin if (z1 < z2) then result := z2 else result := z1; end; Implementierung der Funktion Als Methode von TForm1 Struktur einer Unit 32 unit name; {$mode objfpc}{$H+} interface uses ... Kopf Schlüsselwort unit Das System schriebt den Namen beim Speichern! Interface (Schnittstelle) • Type ... var ... implementation uses ... • Typ – Vereinbarungen • gobale Variablen und Konstanten Implementation type ... • var ... • procedure … end. Auf Alles, was hier deklariert ist, kann von außen (anderen Units) zugriffen werden. Lokale Deklarationen (nur innerhalb der Unit) Implementierung von Prozeduren, Funktionen (Methoden) Projekt BMI 33 Mit einem Programm soll der BodyMass-Index BMI berechnet werden. Eingaben: Gewicht in Kg, Körpergröße in m Ausgabe: BMI-Index Ablauf: Ereignisgesteuert Schreiben Sie ein Programm, das den Body-Mass-Index einer Person ausgibt. 34 Projekt BMI Ergänzen Sie das Programm mit einer Bewertung des BMI nach Alter. Benutzen Sie dazu die folgenden Grundlagen und die Kontexthilfe. Die Tabelle zeigt die „wünschenswerte“ BMI-Werte für verschiedene Altersgruppen: Alter BMI 19-24 Jahre 19-24 25-34 Jahre 20-25 35-44 Jahre 21-26 45-54 Jahre 22-27 55-64 Jahre 23-28 >64 Jahre 24-29 Weitere Informationen unter: https://www.uni-hohenheim.de/wwwin140/info/interaktives/bmi.htm 35 Lösung procedure TGUI.BtberechnenClick(Sender: TObject); var gewicht, groesse, BMI : real; begin //Eingabe gewicht := StrToFloat(EdGewicht.Text); groesse := StrToFloat(EdGroesse.Text); //Verarbeitung BMI := gewicht/groesse/groesse; //Ausgabe PAusgabe.Caption := FloatToStr(BMI); end; Projekt Zahlenraten 36 Aufgabe: Es ist ein Programm zu entwickeln, das ein Zahlenratespiel simuliert. Anforderungen: 1. Der Computer bestimmt eine Zufallszahl (1..100), die der Spieler zu erraten hat. 2. Der Spieler hat er beliebig viele Versuche. 3. Nach jeder Zahleneingabe wird angegeben, ob die Zahl zu groß oder zu klein ist. 4. Hat der Spieler die Zahl erraten, so wird die Anzahl der Versuche und eine Bewertung ausgegeben. 5. Alle Ausgaben werden gelöscht, wenn ein neues Spiel begonnen wird. 6. Sicherheitsprüfung bei der Eingabe der Ratezahll. 7. Feldgröße über ein Edit-Feld eingelesen Datenmodell Anzahl der Versuche: Versuche : integer Zu erratende Zahl: Ratezahl : integer Zufallszahlen Funktion: random z := random(N); ganzzahlige Zufallszahl z mit 0 z < N r := random; Gleitkommazahl 0 r < 1 GUI und Datenmodell 37 Problem • Speicherung der Daten in den GUI-Objekten ist ineffektiv!!! • Besser ist eine Trennung von GUI und Datenmodell Lösung (vorläufig) • Realisierung eines "internen Datenmodell“ mit globalen Variablen als private Atribute des Formulars. • Diese Variablen sind innerhalb des Formularobjekts global. Internes Datenmodell TGUI = class(TForm) {Steuerelemente} Lokale Variablen (temporäre Daten) procedure TGUI.BpruefenClick(...); var procedure FormCreate(Sender: TObject); Zahl : integer; procedure BtEingabeClick(...); kommentar : string; private begin { Private-Deklarationen} //Eingabe RateZahl : integer; Zahl := StrToInt(ETippZahl.text); Versuche : integer; // Verarbeitung public { Public-Deklarationen} end; Versuche := Versuche + 1; if Zahl = Ratezahl then ... end; Spieldaten als private Attribute des Formulars Initialisierung bei Programmstart 38 Ereignis OnCreate des Formulars Die zugehörige Ereignisprozedur FormCreate wird automatisch beim Start des Programms aufgerufen. Anwendungsbeispiel: Initialisierung des Zufallszahlengenerators des Systems durch randomize. Dadurch wird bei jedem Programmstart eine andere Zufallszahlenfolge erzeugt. procedure TGUI.FormCreate(Sender: TObject); begin randomize; end; Teil 3 Übungen Helmut Paulus Speyer, 19.04.13 40 Aufgabe 1 Das Schaltjahr-Problem Die Schaltjahresregelung unseres Kalenders (Gregorianischer Kalender) lautet: Ein Schaltjahr ist ein Jahr, dessen Jahreszahl durch 4 ohne Rest teilbar ist. Ausgenommen davon sind die Jahrhundertwechsel, es sei denn, deren Jahreszahl ist durch 400 ohne Rest teilbar. Es kommt also alle 400 Jahre vor, dass ein Jahrhundertwechsel ein Schaltjahr erzeugt. Das Jahr 2000 ist ein solches Jahr. Zu entwickeln ist ein Programm, das nach Eingabe einer gültigen Jahreszahl prüft, ob dieses Jahr ein Schaltjahr ist. Aufgabe 2 41 Die Entwicklung der Weltbevölkerung schreitet rasch voran: Im Jahr 2012 wurde die 7 Milliardengrenze überschritten. Zur Zeit wächst die Weltbevölkerung jährlich um ca. 1,2 %. Mit Hilfe eines kleinen Programms soll die jährliche Entwicklung verfolgt werden. Datenmodell: Jahr Population WFaktor Prototyp: Interaktionen: : integer; : double; : double; Aktuelle Werte eingeben und die Population des nächsten Jahres berechnen und anzeigen Aktuelle Werte eingeben und die Population des vorherigen Jahres berechnen und angezeigen Population in 10-Jahresschritten voraus- oder zurückberechnen Aufgabe 3 42 Projekt 17 und 4: Es ist ein Programm zu entwickeln, das das bekannte Kartenspiel simuliert. Anforderungen 1. Spielkarten werden durch einen Würfel ersetzt (Wertbereich [1;...;6]). 2. Es werden Zahlen gewürfelt und aufsummiert. Der Spieler kann nach jedem Spielzug entscheiden, ob er aufhört oder weiter spielen will. 3. Ist die Summe größer als 21, so hat der Spieler verloren. Hört der Spieler bei einer Summe kleiner oder gleich 21 auf, wird noch eine Zahl gewürfelt. Ist die neue Summe immer noch kleiner oder gleich 21, so hat der Spieler verloren, andernfalls gewonnen. 4. Alle Ausgaben werden gelöscht, wenn ein neues Spiel begonnen wird. Teil 4 • Objektorientierte Programmierung mit Objekt-Pascal • Übungen Projekt Farbenmischer 44 RGB-Farben bestehen aus einer Mischung von jeweils 3 Farben (rot - grün - blau). Jeder Farbkanal hat 256 Abstufungen: 0 …255. Ziel: Zu entwickeln ist ein Programm, das beliebige RGB-Farben, sowie deren Komplementärfarbe nebeneinander angezeigt . Beispiele: Modellklasse TFarbe 45 Farbmodell Festlegung von: TFarbe - rot : integer - gruen :integer Zugriffsrechten (- private; + public) • Datentypen • Signaturen (Parameter der Methoden) private Attribute - blau : integer; + constructor create Konstruktor + getFarbe : integer; create + setFarbe(r, g, b : integer) • öffentliche Methoden + getrot : integer + getgruen: integer + getblau : integer Konvention - vorangestelltes T bei Datentypen Objekte werden mit Hilfe von Konstruktoren erzeugt. Dabei … Konstruktoren • wird der Speicherbereich eines Objekts anlegt, - constructor (Schlüsselwort) • werden die Attribute mit Standardwerten belegt, • wird eine Referenz auf das Objekt zurückgeben. Implementierung 46 Eigene Unit für die Modellklasse: uFarbe.pas 1. Deklaration der Klasse im Interface unit uFarbe; TFarbe Interface - Frot : integer uses ... - Fgruen :integer type - Fblau : integer; TFarbe = Class + constructor create private + getFarbe : integer; rot, blau, gruen : integer; public constructor create; + setFarbe(r, g, b : integer) + getrot : integer procedure setFarbe(r,g,b : integer); + getgruen: integer function getFarbe : integer; + getblau : integer function getrot : integer; function getgruen: integer; function getblau : integer; end; Implementation ... Implementierung 47 2. Implementierung der Methoden im Implementation - Bereich der Unit ... implementation constructor TFarbe.create; begin rot := 255; gruen := 255; blau := 255; end; function TFarbe.getFarbe : Integer; begin result := blau*256*256+Gruen*256+rot; end; procedure TFarbe.setFarbe(r,g,b : integer); begin rot := r mod 256; gruen := g mod 256; blau end; ... := b mod 256; GUI 48 Formular-Unit: GUI-Objekte: TLabel TEdit TButton TShape TButton Modellobjekt verwalten 49 Das Formular verwaltet die GUI-Objekte und das Modellobjekt. uses Windows, Messages, SysUtils, Classes, uFarbe; Unit einbinden type Tgui = class(TForm) Farbmischer: TGroupBox; Label1: TLabel; . . . private { Private-Deklarationen } Farbe : TFarbe; procedure aktualisiere; //Anzeigen public { Public-Deklarationen } . . . Referenzvariable für das Farbobjekt deklarieren (Hat- Beziehung) Objekte erzeugen und freigeben 50 Die GUI-Objekte, die zur Entwurfszeit ins Formular eingefügt wurden, werden automatisch erzeugt und zerstört. Das Farbobjekt wird zur Laufzeit erzeugt und zerstört werden. Z. B.: Erzeugung mit dem OnCreate-Ereignis Schema: obj := Klasse.create; procedure TGUI.FormCreate(...); begin Farbe := TFarbe.create; ... Zeiger auf ein Farbobjekt hat-Beziehung end; Zerstörung mit dem OnDestroy-Ereignis Procedure TGUI.FormDestroy(...); begin Farbe.Free; end; Speicherbereich freigeben geerbter Destruktor 51 Aktualisierung von Model und View Ereignismethode //Datenfluss: Controller Modell procedure TGUI.okBtnClick(Sender: TObject); //Modelldaten schreiben var r, g, b : integer; begin r := StrToInt(Erot.text); g := strtoint(Egruen.text); b := strtoint(Eblau.text); Farbe.setFarbe(r,g,b); //Werte im Modellobjekt speichern aktualisiere; end; //Aktualisierung der Anzeige durch Abfragen //Datenfluss: Modell View procedure TGUI.aktualisiere; //Modelldaten abfragen begin FarbBox.brush.color := Farbe.getFarbe; KFarbBox.brush.color := clwhite - Farbe.getFarbe; end; MVC-Muster 52 Ziel: Trennung von Datenhaltung und -verarbeitung, Darstellung und Steuerung. Modell Interne Repräsentation der Daten mit Methoden zum Ändern und Abfragen View Ansicht, Darstellung: Ein Modell kann durch mehrere Views angezeigt werden, welche unterschiedliche Sichtweisen des Models darstellen. Controller Steuerung: Verarbeitung der Benutzereingaben View und Controller bilden zusammen die Benutzeroberfläche (GUI). Controller Steuerung View Ansicht GUI schreibt liest informiert Model Fachkonzept Aufgabe 1 53 1. Testen Sie das Programm ‚Farben0’ und verfolgen Sie den Ablauf mit Hilfe des EinzelschrittModus. 2. Erweitern Sie das Farbemodell um folgende Methoden a) TFarbe.getKomplement (Komplementärfarbe) b) TFarbe.toHTML (HTML- Code) Bsp.: #AFB055, verwenden Sie die Funktion InttoHex() c) Binden Sie beide Methoden in die Anwendung ein. 3. Entwickeln Sie eine zweite Benutzungsoberfläche, die die RGB-Farben einzeln anzeigt. (z. B.: in drei Shape-Komponenten) Binden Sie das Farbmodell an die entwickelte Benutzeroberfläche an. Links 54 Lazarus Tools, Tutorials … • http://wiki.lazarus.freepascal.org/Lazarus_Documentation/de • http://wiki.lazarus.freepascal.org/Lazarus_IDE_Tools/de#Find_Declaration • http://wiki.lazarus.freepascal.org/Lazarus_Tutorial/de Grundlagen ObjektPascal • http://www.delphi-treff.de/ Unterrichtsmaterialien Bildungsserver Informatik RP • http://informatik.bildung-rp.de K. Merkert: http://www.hsg-kl.de/faecher/inf/delphi/index.php Siegfried Spolwig / Johann Penon • http://oszhdl.be.schule.de/gymnasium/faecher/informatik/lazarus/index.html Martin Jakobs • http://www.martinjakobs.de/pages/objektorientierte-programmierung.php Joachim Mohr • http://www.kilchb.de/lektionen.html UML-Werkzeug: • UML-Editor : UMLed.exe http://www.kubitz-online.de