next up previous contents index
Next: Bibliography Up: C++-Entwicklung mit Linux Previous: Werkzeuge für die Softwareentwicklung   Contents   Index

Subsections


Integrierte Entwicklungsumgebungen

Bisher haben Sie neben der Sprache C++ auch eine Reihe von Werkzeugen kennen gelernt, mit denen Sie eigentlich alle Entwicklungsaufgaben erledigen könnten. Das ist jedoch zuweilen etwas mühsam; während Freaks auf ihre Kommandozeilentools schwören, mutet Ihnen die Arbeitsweise vielleicht ein wenig archaisch an. Wesentlich bequemer und damit auch produktiver wird die Programmierung mit integrierten Entwicklungsumgebungen, Integrated Development Environments oder kurz IDEs. Wenn Sie schon Programme unter Windows oder auf dem Mac geschrieben haben, kennen Sie sicher Umgebungen wie Microsoft Visual Studio, Borland Delphi oder Metrowerks CodeWarrior.

Diese verfügen alle über folgende Merkmale:

  1. Ein Editor steht zur Verfügung, der den Programmierer durch Syntaxeinfärbung, automatisches Einrücken und Querverbindungen mit der Dokumentation unterstützt.
  2. Der Compiler kann direkt aus der IDE gestartet werden.
  3. Die Compiler-Optionen werden über Menüs beziehungsweise Dialoge eingestellt.
  4. Codestellen, an denen der Compiler Fehler findet, werden automatisch angezeigt.
  5. Die erzeugten Programme können sofort gestartet werden. Bei der Fehlersuche mit dem Debugger werden die gerade durchlaufenen Quelltexte im Editor angezeigt; Haltepunkte und Einzelschritte können dort aktiviert werden.
  6. Die Dateien, die zu einem Projekt gehören, werden über einen Dialog festgelegt. Makefiles werden automatisch erzeugt beziehungsweise sind überflüssig.
  7. Die Versionsverwaltung ist in die IDE eingebunden, so dass die Dateien über den Editor aus- und eingecheckt werden können.
Ich will Ihnen in diesem Kapitel vor allem eine IDE vorstellen, die alle diese Kriterien erfüllt (und noch einige mehr): KDevelop aus dem KDE-Projekt. Wie alle in diesem Umfeld entstandene Software ist auch KDevelop ein Open-Source-Projekt unter GPL. Sie finden es auch auf beiliegender CD-ROM und können es gleich installieren. Ab Seite [*] werden wir uns ausführlich damit beschäftigen.

Doch zunächst will ich Ihnen zeigen, dass auch der bereits vorgestellte XEmacs zu einer fast vollwertigen IDE werden kann. Abschließend werde ich Sie ab Seite [*] noch auf einige weitere interessante IDEs hinweisen.

XEmacs als IDE

Bereits als wir ab Seite [*] den XEmacs näher betrachteten, habe ich Sie darauf aufmerksam gemacht, dass er eigentlich viel mehr als nur ein Editor ist. Es gibt für ihn so viele Erweiterungen, dass Sie nichts anderes mehr benötigen. Natürlich gilt das auch im Hinblick auf die Programmierung. Wir wollen uns nun die wichtigsten Funktionen ansehen, die Sie bei der Verwendung des XEmacs als IDE brauchen werden.

Obwohl ich hier nur vom XEmacs rede, funktionieren die meisten der vorgestellten Merkmale auch beim GNU Emacs.

Der Editor

Dass der Editor Syntaxeinfärbung, Markierung von Klammern und automatisches Einrücken beherrscht, habe ich Ihnen schon auf Seite [*] gezeigt. Anhand der Dateiendung (.cc, .C, .cpp, .cxx, .hh oder .hxx) erkennt er automatisch, dass es sich dabei um einen C++-Quelltext handelt und passt seinen Modus entsprechend an. Auch die Navigationsmöglichkeiten ergeben sich daraus.

Liegt die Dokumentation zu einer Funktion im UNIX-man-Format vor, so können Sie diese direkt im XEmacs aufrufen. Das ist zum Beispiel für die C-Standardbibliothek und einige sonstige Bibliotheken der Fall.

Angenommen, Sie möchten die Bedeutung der Parameter der Funktion strstr() wissen. Dann klicken Sie doppelt darauf, um sie zu markieren. Dann wählen Sie aus dem Menü HELP | MANUALS | UNIX MANUAL und erhalten in der Echo-Zeile, also der untersten Zeile des Fensters, die Meldung:

Manual entry (default strstr): 

Hier müssen Sie nur noch die Eingabetaste drücken und schon haben Sie die gewünschte Information vor sich.

Start des Compilers

Wenn Sie mit dem XEmacs Programme entwickeln, ist es am sinnvollsten, mit Makefiles zu arbeiten. Natürlich können Sie auch hier die Quelldateien einzeln übersetzen und linken lassen, aber das ist genauso mühselig wie über die Kommandozeile. Gehen wir also davon aus, Sie hätten bereits ein Makefile (diese lassen sich ja auch sehr komfortabel mit XEmacs erstellen und bearbeiten).

Um den Compiler zu starten, gibt es wieder viele Wege: die Schaltfläche COMPILE, der Menüpunkt TOOLS | COMPILE oder ganz klassisch über die Tastatur: Alt+X und dann compile eingeben. Dann werden Sie noch gefragt, wie Sie make aufrufen wollen. Die Vorgabe enthält die Option -k, die dafür sorgt, dass der Übersetzungsvorgang nicht bei einer fehlerhaften Datei abgebrochen wird, sondern dass andere Dateien, die von dieser unabhängig sind, auch noch kompiliert werden.

Treten bei der Übersetzung Fehler auf, so werden die entsprechenden Meldungen im unteren Teil des Fensters angezeigt. Mit einem Klick darauf gelangen Sie sofort an die angegebene Stelle im Quelltext und können nach der Ursache suchen. Im Programm in Abbildung [*] fehlt einfach das Semikolon nach der Anweisung innerhalb der Schleife.

Figure: Meldet der Compiler Fehler, springt der XEmacs bei einem Klick in den Quelltext.



\resizebox*{1\columnwidth}{!}{\includegraphics{/usr/homes/thomas/cpp/cpp_linux/Text/images/xem-prgerrors.eps}}

Start des Programms und des Debuggers

Ebenso leicht ist es, das erfolgreich erzeugte Programm aus dem XEmacs zu starten. Da es ja auch einem Shell-Kommando entspricht, müssen Sie nur noch darauf achten, den richtigen Pfad zu verwenden. Als lokales Verzeichnis sieht der XEmacs immer das Verzeichnis an, aus dem er gestartet wurde. Liegt Ihr Programm nicht dort, müssen Sie einen relativen oder absoluten Pfad mit angeben. Rufen Sie also TOOLS | SHELL COMMAND oder Alt+! auf und geben Sie den Namen Ihres Programms und gegebenenfalls weitere Argumente ein. Wie Sie wissen, müssen Sie das nur das erste Mal tun; der XEmacs merkt sich solche Eingaben und lässt Sie mittels der Tasten $\uparrow$ und $\downarrow$ auf frühere zugreifen. Die Ausgaben Ihres Programms erscheinen dann in einem Fenster des XEmacs.

Wenn Sie Ihr Programm debuggen wollen, gehen Sie ähnlich vor. Standardmäßig ist der XEmacs mit dem gdb integriert, also dem textorientierten Debugger, den Sie von Seite [*] kennen. Wenn Sie nun TOOLS | DEBUG (GDB) wählen, werden Sie noch nach dem Namen der ausführbaren Datei gefragt und los geht's. Nun ändert sich auch die Leiste der Schaltflächen und es erscheinen solche, die für das Debuggen gebraucht werden (Abbildung [*]); wenn Sie den Mauszeiger über eine davon bewegen, können Sie deren Bedeutung in der Echo-Zeile lesen.

Figure: Beim Start des gdb aus dem XEmacs passen sich auch die Schaltflächen an.



\resizebox*{1\columnwidth}{!}{\includegraphics{/usr/homes/thomas/cpp/cpp_linux/Text/images/xem-gdb.eps}}



Nun können Sie entweder über die Schaltflächen oder direkt an der Eingabeaufforderung des gdb alle bekannten Befehle aufrufen und auf diese Weise Schritt für Schritt die Fehler in Ihrem Programm suchen.

Versionsverwaltung mit XEmacs

Auch die Funktionen zur Versionskontrolle sind direkt in den XEmacs integriert. Unter Linux wird dabei standardmäßig RCS verwendet (siehe Seite [*]). Aber auch CVS (siehe Seite [*]) und andere werden unterstützt. Die entsprechenden Funktionen sind hinter dem Menüpunkt TOOLS | VC verborgen - aber natürlich gibt es für alles auch wieder Tastenkürzel. Wenn Sie sie nicht standardmäßig aktiviert haben, müssen Sie die Unterstützung für die Versionsverwaltung vor dem ersten Aufruf mit TOOLS | VC | LOAD VC laden.

Jede Versionsverwaltung legt eine Reihe von Dateien zur eigenen Buchhaltung an. XEmacs orientiert sich an diesen und versucht, das System, das jeweils für die aktuelle Datei passt, auch zu unterstützen. Gibt es also beispielsweise ein Unterverzeichnis RCS, so werden die RCS-Funktionen aktiviert und so weiter. Die Aktionen, die XEmacs unter TOOLS | VC bietet, beziehen sich vorwiegend auf die Datei im aktuellen Puffer.

Die wichtigsten Funktionen für RCS sind:

Interessant ist es auch, die aktuell bearbeitete Version einer Datei mit der archivierten zu vergleichen. Dazu bietet sich Ediff an, zu dem wir gleich kommen.

Die wichtigsten Funktionen für CVS sind:

Darüber hinaus gibt es noch ein paar weitere Funktionen, deren Bedeutungen aber aus den Menüpunkten schnell einsichtig werden.

Dateivergleich mit Ediff

Ein sehr hilfreiches Werkzeug zum Vergleich von Dateien, Verzeichnissen und anderem ist Ediff. Sie erreichen es über das Menü TOOLS | COMPARE des XEmacs. Wenn Sie das Untermenü öffnen, sehen Sie bereits die Möglichkeiten, die Ihnen Ediff bietet. Wir wollen hier zwei Dateien miteinander vergleichen, genauer zwei Versionen einer Datei.

Dazu rufen Sie TOOLS | COMPARE | FILE WITH REVISION auf. Um die Fragen, die XEmacs stellt, müssen Sie sich nicht weiter kümmern; Sie möchten ja ohnehin nur den Standardfall bearbeiten, nämlich den aktuellen Puffer mit seiner letzten archivierten Version vergleichen.

Anschließend öffnet sich ein kleines zusätzliches Steuerfenster, über das Sie Ihre Ediff-Befehle geben können. Dabei müssen Sie beachten, dass die Ediff-Tastenkombinationen nur dann funktionieren, wenn das Steuerfenster das aktive ist. Gerade wenn Sie Ihre Oberfläche so eingestellt haben, dass die Aktivierung der Fenster schon bei der Positionierung des Mauszeigers darüber erfolgen soll, kann es immer wieder zu Problemen kommen, die Ediff mit einem Piepser quittiert.

Das Arbeitsfenster des XEmacs teilt sich nun in zwei Bereiche auf, die die beiden miteinander zu vergleichenden Dateien (hier Versionen) enthalten (Abbildung [*]). Aus der jeweiligen Statuszeile erfahren Sie, welche welche ist.

Mit Hilfe von Ediff navigieren Sie nun durch die sich unterscheidenden Bereiche der Dateien. Diese sind jeweils andersfarbig hervorgehoben. Abweichende Zeilen werden als Ganzes markiert; einzelne Abweichungen darin werden mit einer weiteren Farbe hervorgehoben. In Prosa klingt das alles sehr kompliziert, wird aber beim konkreten Einsatz schnell einsichtig.

Figure: Die Unterschiede zwischen den Dateien werden durch verschiedene Farben hervorgehoben.


\resizebox*{1\columnwidth}{!}{\includegraphics{/usr/homes/thomas/cpp/cpp_linux/Text/images/xem-ediff.eps}}


Auch während des Vergleiches können Sie beide Fenster noch editieren (sofern nicht eines davon schreibgeschützt ist). Die meisten Aktionen geben Sie aber durch einfache Tasten über das Ediff-Fenster an. Die wichtigsten davon sind:

Zusammenfassung

Sie haben gesehen, dass der XEmacs sich durchaus gut für die Programmierung eignet. Viele der bekannten Open-Source-Programmpakete wurden mit ihm geschrieben. Er enthält einen komfortablen Editor mit Syntaxeinfärbung und Einrückung, erlaubt das Starten des Compilers und das Springen zu Fehlerstellen, integriert den Debugger und die Versionsverwaltung und bietet mit Ediff ein äußerst praktisches Werkzeug zum Vergleich von Dateien und Versionen.

Von den Kriterien für IDEs, die wir am Anfang des Kapitels aufgestellt haben, erfüllt er die Punkte 3 und 6 nicht. Gerade die Verwaltung größerer Projekte mit mehreren Abhängigkeiten wird daher schwierig. Für Umsteiger aus der Windows-Welt sind vielleicht gerade diese Aspekte entscheidend, da sie den Umgang mit Make-Dateien nicht gewohnt sind. Aber auch diese Funktionen wird der XEmacs früher oder später beherrschen.


KDevelop

Auch das KDE-Projekt hat mit KDevelop eine eigene integrierte Entwicklungsumgebung hervorgebracht. Wie alles in KDE steht auch diese unter GPL und ist frei im Quelltext verfügbar. Die aktuellste Version erhalten Sie stets von www.kdevelop.org.

Überblick

KDevelop ist mittlerweile zu einer sehr komfortablen IDE herangereift, die unter Linux unübertroffen ist. Besonders hervorzuheben ist zunächst die gute Onlinehilfe, die für ein Open-Source-Projekt ja nicht selbstverständlich ist. Neben einem Benutzer- und einem Entwickler-Handbuch ist auch ein Tutorial und eine C/C++-Referenz sowie eine KDE-Bibliotheksreferenz verfügbar - und das zum Teil in mehreren Sprachen! Für Einsteiger hilfreich ist auch der Tipp des Tages, der auf Wunsch bei jedem Start von KDevelop erscheint.

Das Programm erfüllt alle Kriterien vom Anfang dieses Kapitels, bringt einen komfortablen Editor mit, startet den Compiler (standardmäßig natürlich den GCC) direkt aus der IDE, lässt die Optionen für Kompilieren, Linken und make über Dialoge einstellen, springt aus der Fehlerausgabe direkt durch Doppelklick an die entsprechende Programmstelle, bindet einen Debugger ein, verwaltet automatisch die Makefiles und hat die Versionsverwaltung integriert.

Aber KDevelop geht noch sehr viel weiter, als nur diese Kriterien zu erfüllen. Die Erzeugung der Make-Dateien macht beispielsweise intensiv von autoconf Gebrauch, um die Generierung automatisch an die lokale Hard- und Softwareumgebung anzupassen. Außerdem ist mit KBabel ein zusätzliches Werkzeug direkt angebunden, um die Applikationen von Anfang an mehrsprachig zu entwickeln.

Und im Gegensatz zu allen anderen hier vorgestellten IDEs unterstützt KDevelop auch die Entwicklung von grafischen Benutzeroberflächen. Dazu nutzt es die in KDE verwendeten Prinzipien der Programmierung von grafischen Anwendungen auf der Basis der Klassenbibliothek Qt. Für die Gestaltung von Dialogen und fensterbasierten Applikationen bringt KDevelop kein eigenes Werkzeug mit, sondern setzt den Qt Designer ein, der vom Qt-Hersteller Trolltech stammt. Die dort erzeugten Dateien kann KDevelop in seine Projekte einbinden, daraus die nötigen Klassen generieren und übersetzen. Für andere Aufgaben gibt es wieder andere externe Werkzeuge, etwa KIconEdit für die Gestaltung von Icons.

Generell gilt auch auch bei KDevelop, was wir noch bei anderen IDEs feststellen werden und was im Gegensatz zu den unter Windows üblichen Gepflogenheiten steht: Die IDE ist in weiten Teilen nur ein Frontend, ein grafisch bedienbarer Zugriffsweg auf die darunter liegenden Werkzeuge. Compiler, Debugger etc. sind nicht im Lieferumfang enthalten, sondern als externe Tools vorausgesetzt und eingebunden. Auf diese Weise erreicht die IDE aber auch ein hohes Maß an Flexibilität, und die Entwicklung kann sich auf die eigene Funktionalität konzentrieren.


Installation und Konfiguration

Die eben noch gerühmte Flexibilität hat leider auch eine Schattenseite: KDevelop ist von der vorhandenen Installation einer ganzen Reihe anderer Pakete abhängig. Und damit es nicht zu Inkonsistenzen kommt, sollten sich alle auf demselben Stand befinden. Wenn Sie KDevelop aus Ihrer Linux-Distribution installieren, sorgt deren Installationsprogramm im Allgemeinen dafür, dass die Versionsstände aller Pakete miteinander verträglich sind. Falls Sie KDevelop jedoch selbst (als RPM oder aus dem Quellcode) auf Ihrem Rechner einrichten wollen, sollten Sie darauf achten, folgende Pakete in der jeweils zugehörigen Version verfügbar zu haben: KDevelop ist insbesondere so eng mit KDE verwoben, dass Sie stets auf eine Konsistenz der Versionen achten sollten. So erscheint mit jeder neuen Ausgabe von KDE auch eine neue KDevelop-Version.

Außerdem sind die folgenden zusätzlichen Werkzeuge zwar optional, aber recht hilfreich und für bestimmte Funktionen erforderlich:

Näheres (zum Beispiel die genauen Versionsnummern) können Sie der KDevelop-Website oder der mitgelieferten Dokumentation von KDevelop entnehmen.

Wenn Sie nach der Installation des rpm-Paketes oder aus dem übersetzten Sourcecode KDevelop das erste Mal aufrufen, müssen Sie noch einige Einstellungen festlegen. So können Sie beispielsweise wählen, ob Sie für Syntaxhervorhebungen eher den Stil von KDevelop, den des Emacs oder von KWrite (siehe auch Seite [*]) wünschen. Sie können außerdem festlegen, wie sich die Fenster von KDevelop auf dem Bildschirm verteilen sollen (MDI, Top-Frame, Reiter). Anschließend prüft die Installationsroutine Ihr System und weist Sie gegebenenfalls auf fehlende Programme oder Dokumentationen hin, die Sie bei Ihrer Arbeit mit KDevelop brauchen könnten. Zum Schluss erzeugt KDevelop wenn nötig noch einen Suchindex für das von Ihnen installierte Dokumentationsmaterial zu KDE und Qt, damit Sie bequemer mit Suchbegriffen darauf zugreifen können.

Ein Vorteil von KDevelop ist, dass Sie damit auch Applikationen für neuere Qt- und KDE-Versionen erstellen können. Dazu müssen Sie deren Bibliotheken lediglich an geeigneter Stelle ablegen und im Dialog OPTIONEN | KDEVELOP-EINRICHTUNG unter PFAD die jeweiligen Verzeichnisse eintragen. Auch andere Basiseinstellungen können Sie in diesem Dialog vornehmen.

Die KDevelop-Entwicklungsumgebung

Die Benutzeroberfläche von KDevelop lehnt sich in ihrer Gestaltung an bekannte IDEs wie Visual Studio 6 oder Borland C++Builder an, so dass Ihnen der Umstieg von diesen nicht allzu schwer fallen dürfte. Gleichzeitig enthält es aber einige raffinierte Besonderheiten.

Das Hauptfenster

Das Hauptfenster von KDevelop (Abbildung [*]Fig:KDevelop zeigt die Version 2.1) ist in vier Teile gegliedert:

Figure: Über das Hauptfenster von KDevelop sind Header, Implementationsdateien, Dokumentation und Werkzeuge erreichbar.

\resizebox*{1\columnwidth}{!}{\includegraphics{/usr/homes/thomas/cpp/cpp_linux/Text/images/kdevel.eps}}

Der Editor hält sich an alle Konventionen, die Sie aus anderen Programmen für KDE kennen. So können Sie mit Strg+X ausschneiden, mit Strg+Z die letzte Aktion rückgängig machen, mit Strg+S speichern und so fort. Die Syntaxeinfärbung ist übersichtlich, ein automatisches Einrücken ist ebenso möglich wie das automatische Einfügen von schließenden Klammern beim Tippen oder das vertikale Selektieren (zu aktivieren unter EINSTELLUNGEN | EDITOR). Zudem können Sie auch bei KDevelop Lesezeichen in den Quelltexten setzen, zu denen Sie dann später springen können.

Und noch eine nette Funktion bei KDevelop: Wenn Sie eine Datei geändert haben, die Änderungen aber noch nicht gespeichert sind, so kommt zu dem kugelartigen grünen Symbol in der KDE-Kontrollleiste noch ein zweites hinzu: eine Diskette. Auf diese Weise erkennen Sie sofort, wenn Sie irgendwo das Speichern vergessen haben - auch wenn Sie gerade in einem anderen Programm arbeiten.

Navigation und Hilfe

Ganz nützlich ist es, dass viele Funktionen über Kontextmenüs erreichbar sind. Wenn Sie etwa im Editor gerade eine Implementierungsdatei bearbeiten, werden Sie öfter mal zur zugehörigen Header-Datei umschalten müssen, um dort etwas nachzuschlagen oder zu ändern. Wenn Sie aus dem Kontextmenü UMSCHALTEN ZWISCHEN HEADER/QUELLTEXT wählen, gelangen Sie ohne langes Suchen direkt dorthin.

Apropos suchen: Natürlich können Sie auch in Ihrem Editor nach einem Begriff suchen. KDevelop hat zusätzlich das kleine Werkzeug grep eingebunden, mit dem Sie in verschiedenen Dateien gleichzeitig suchen können. Markieren Sie einfach den gewünschten Ausdruck und wählen Sie GREP aus dem Kontextmenü.

Im selben Kontextmenü darunter gibt es noch zwei andere praktische Funktionen: SUCHEN und MANPAGE. Die erste sucht nach dem markierten Begriff in der eingerichteten Dokumentation (mittels der durch htDig eingerichteten Volltextsuche), die zweite versucht, eine mögliche zugehörige man-Seite zu öffnen.

KDevelop orientiert sich immer mehr an den großen IDEs unter Windows wie Microsoft Visual Studio oder Borland C++Builder und versucht, deren Funktionsmerkmale zum Teil nachzubilden. Dazu gehört auch die Code-Vervollständigung, die aber derzeit noch als experimental gekennzeichnet ist. Nehmen wir an, Sie haben ein Objekt einer bestimmten Klasse definiert und tippen dieses in Ihrem Quelltext wieder ein, um eine Methode davon aufzurufen. Dazu setzen Sie hinter den Objektnamen einen . oder einen -> (je nachdem, ob Referenz oder Zeiger). Schon klappt unterhalb der Eingabezeile ein kleines Fenster auf, das Ihnen die vorhandenen Methoden dieser Klasse auflistet (siehe Abbildung [*]) - allerdings nur die der Klasse selbst, nicht die einer Basisklasse. Wenn Sie nun die öffnende Klammer für die Parameter eingeben, erhalten Sie ein weiteres Hilfefensterchen, das angibt, welche Parameter diese Methode erwartet.

Figure: Mit Auto-Vervollständigung können Sie aus den vorhandenen Methoden einer Klasse auswählen.



\resizebox*{1\columnwidth}{!}{\includegraphics{images/kdev-codecompletion.eps}}


Der Anwendungsassistent

Zunächst müssen Sie ein neues Projekt anlegen, wenn Sie etwas mit KDevelop entwickeln wollen. Über PROJEKT | NEU erreichen Sie den Anwendungsassistenten, der Ihnen dabei zur Hand geht.

Auf der ersten Seite legen Sie fest, von welchem Typ Ihr Projekt sein soll.

Die nächste Seite dient der Festlegung von Projekteinstellungen. Neben Projektname, Pfad, Autor etc. können Sie auch wählen, welche zusätzlichen Dateien zu Ihrem Projekt hinzukopiert werden sollen. KDevelop geht davon aus, dass man damit nur GPL-Software entwickelt, und stellt die dafür typischen Dateien wie INSTALL, README, COPYING zur Verfügung. Falls Sie eine Benutzerdokumentation oder eine API-Dokumentation anlegen wollen, können Sie auch dafür Gerüste generieren lassen. Schließlich haben Sie an dieser Stelle noch die Möglichkeit, ein Icon für Ihre Applikation anzugeben.

Falls Sie auf eine Versionsverwaltung mit CVS (siehe Seite [*]) verzichten, können Sie nun sofort auf ERSTELLEN klicken. Anderenfalls finden Sie auf der nächsten Seite die dafür nötigen Einstellungen vor, zum Beispiel der Pfad zum CVSROOT-Verzeichnis.

Figure: Der Anwendungsassistent von KDevelop überprüft mittels configure Ihre lokale Umgebung.



\resizebox*{0.75\columnwidth}{!}{\includegraphics{images/kdevl-appwizard.eps}}

Der letzte Schritt ist die eigentliche Erstellung des Projekts. Hierbei nimmt KDevelop eine Vorlage für den von Ihnen ausgewählten Projekttyp, kopiert die Dateien zunächst in das Projektverzeichnis und passt sie anschließend sowohl an Ihre Einstellungen aus den vorangegangenen Dialogen als auch an Ihre lokale Hard- und Softwareumgebung (mittels autoconf beziehungsweise configure) an. Einen Teil der Ausgabe sehen Sie in Abbildung [*]Fig:KDevel-AppWizard.

Die Projekteinstellungen

Alle Einstellungen, die das aktuelle Projekt betreffen, können Sie über den Dialog PROJEKT-OPTIONEN ansehen und bearbeiten; Sie erreichen ihn über den Menüpunkt PROJEKT | OPTIONEN oder die Taste F7. Die Projekt-Optionen sind in mehrere Bereiche aufgeteilt, je nach darunter liegendem Werkzeug.

Die ALLGEMEINEN EINSTELLUNGEN sind die einfachsten. Hier finden Sie die Angaben aus der ersten Seite des Anwendungsassistenten wieder, also Programmname, Name und E-Mail-Adresse des Autors, Versionsnummer sowie die Art der eingesetzten Versionsverwaltung.

Etwas kniffliger wird es bei den CONFIGURE-EINSTELLUNGEN. Hier können Sie ein paar der vordefinierten Einstellungen für das Programm configure ändern. Damit ist der autoconf-Mechanismus gemeint: Aus Ihren Angaben und einer automatischen Überprüfung Ihrer Systemumgebung erzeugt dieses Werkzeug die Make-Dateien, mit deren Hilfe KDevelop (beziehungsweise natürlich der GCC) Ihre Anwendung schließlich kompiliert. Zum Glück müssen Sie im Allgemeinen an diesen Einstellungen nichts ändern.

Unter COMPILER-EINSTELLUNGEN (Abbildung [*]) finden Sie einige Angaben vor, die Sie normalerweise in Form von Compiler-Schaltern beim Aufruf des GCC übergeben. KDevelop nimmt diese hier in etwas bequemerer Form für Sie auf und erzeugt daraus dann die Parameter für das Kompilieren. Ganz praktisch ist die Möglichkeit, einen Satz von Einstellungen komplett mit einer Bezeichnung zu versehen und so schnell zwischen verschiedenen Varianten (zum Beispiel für Debug- und Release-Versionen) hin- und herschalten zu können. Ansonsten bietet Ihnen dieser Dialog den Zugriff auf die gängigsten Einstellungen an: Eine Reihe von Warnungen können Sie ebenso an- und abschalten wie den Optimierungsgrad oder die Debug-Informationen.

Figure: In den Projekt-Optionen können Sie unter anderem die zu verwendenden Compiler-Schalter festlegen.



\resizebox*{1\columnwidth}{!}{\includegraphics{images/kdev-optionen.eps}}

Die LINKER-OPTIONEN legen fest, welche Bibliotheken zu einem Projekt hinzugebunden werden sollen. Wenn Sie Ihr Projekt mit Hilfe des Assistenten erzeugt haben, sorgt dieser bereits dafür, dass hier die notwendigen Bibliotheken für das Grundgerüst angekreuzt sind. Die weiteren hängen davon ab, welche aus der Liste Sie tatsächlich verwenden. Wenn Sie eine Bibliothek einsetzen, die nicht verzeichnet ist, so müssen Sie den dafür nötigen Linker-Parameter angeben (also zum Beispiel -lxy für die libxy.a, siehe auch Seite [*] und Seite [*]).

Ähnlich sieht es auch bei den MAKE-OPTIONEN aus. Die Kontrollkästchen im oberen Teil geben die wichtigsten Schalter an, die bei make zur Verfügung stehen (siehe auch Seite [*]), zum Beispiel VORRANG FÜR UMGEBUNGSVARIABLEN oder NACH FEHLERN FORTFAHREN. Zudem lässt sich die Zahl der gleichzeitigen Compile-Jobs einstellen, die ausgeführt werden sollen. Eine weitere Auswahlliste betrifft jedoch mehr das Verhalten von KDevelop selbst: Sie können bei NEU ERSTELLEN BEI AUSFÜHREN/DEBUG festlegen, ob die Umgebung Ihr Programm neu erstellen soll, wenn Sie es ausführen oder im Debugger starten.

Schließlich finden Sie unter der Rubrik AUSFÜHRBARE DATEI noch die Möglichkeit, einen anderen Namen für die ausführbare Datei, die vom Projekt erzeugt wird, zu vergeben und den Pfad zum libtool zu ändern.


Mit Konsolenanwendungen arbeiten

Die Beispielprogramme in diesem Buch waren bislang alle reine Konsolenanwendungen, also Anwendungen, die direkt auf der Kommandozeile ausgeführt werden und Ausgaben auf den Standardausgabekanal schreiben. Obwohl KDevelop auf Applikationen mit grafischen Benutzeroberflächen ausgerichtet ist, können Sie damit auch gut Konsolenprogramme entwickeln, übersetzen und pflegen.


Eine neue Anwendung beginnen

Wenn Sie eines der Beispielprogramme selbst eingeben und dazu KDevelop einsetzen möchten, beginnen Sie mit einem leeren Projekt:

  1. Wählen Sie PROJEKT | NEU. Im Anwendungsassistenten wählen Sie dann TERMINAL | C++.
  2. Geben Sie ein Projektverzeichnis und einen Projektnamen vor. Schalten Sie die Kontrollkästchen GNU-STANDARDDATEIEN, BENUTZERDOKUMENTATION und LSM-DATEI aus - diese benötigen Sie hierbei nicht. Wenn Sie möchten, können Sie noch Ihren Namen und Ihre E-Mail-Adresse angeben.
  3. Die VCS-Unterstützung können Sie überspringen; für einfache Beispiele können Sie auf Versionskontrolle verzichten.
  4. Mit den Vorlagen für die Köpfe der Header- und Implementierungsdateien können Sie nach Ihren Vorlieben verfahren: beibehalten, ändern oder abschalten.
  5. Wenn Sie nun auf ERSTELLEN klicken, arbeitet der Anwendungsassistent erst einmal einige Zeit vor sich hin. Sobald Sie READY lesen, können Sie den Dialog beruhigt über BEENDEN schließen.

Die Vorgabe ist, dass sich die Funktion main() in einer Datei namens main.cpp befindet. Bei kleineren Beispielen reicht diese Datei bereits vollkommen aus. Wenn Sie weitere Dateien benötigen, können Sie diese über DATEI | NEU erzeugen und auch gleich dem Projekt hinzufügen.

Der Assistent hat bereits etwas Code in die Datei eingefügt: eine Ausgabe des berühmten Hello World! in der Form

#ifdef HAVE_CONFIG_H

#include <config.h>

#endif

  

#include <iostream.h>

#include <stdlib.h>

  

int main(int argc, char *argv[])

{

  cout << ``Hello, World!`` << endl;

  

  return EXIT_SUCCESS;

}

Es genügt, die Zeile mit cout zu entfernen und an deren Stelle Ihre Befehle einzusetzen. Den Rest können Sie im Allgemeinen beibehalten, wenn das jeweilige Beispielprogramm nichts anderes sagt.

Mit ERSTELLEN | ERSTELLEN oder der entsprechenden Schaltfläche beziehungsweise der Taste F8 lässt sich Ihr Programm übersetzen. Wenn Sie einen Fehler gemacht haben, den der Compiler moniert, so erscheint diese Meldung im Ausgabefenster unterhalb des Editors. Ein Doppelklick darauf genügt, und Sie landen wieder im Editor an der Stelle, die den Fehler verursacht hat.

Die Anwendung starten Sie mit ERSTELLEN | AUSFÜHREN oder der Taste F9. KDevelop führt eine Konsolenapplikation auch in einer Konsole aus. Es erscheint also ein Terminalfenster, in dem die Ausgaben (oder auch Eingabeaufforderungen) Ihres Programms stehen. Damit dieses Fenster nicht nach Programmende sofort wieder verschwindet, ist eine Pausenfunktion eingebaut. Sie müssen zunächst die Eingabetaste drücken, bevor es sich schließt. (Es kann übrigens sein, dass es KDE dabei allzu gut mit Ihnen meint und bei jedem Start dieser Konsole seinen Tipp des Tages einblendet. Dies stellen Sie ab, in dem Sie das Kästchen BEIM START ANZEIGEN deaktivieren.)

Das Verzeichnis, in dem KDevelop die Quellen Ihrer Anwendung abgelegt hat, ist übrigens gut bevölkert. Der Assistent hat dort eine ganze Reihe von Dateien erzeugt, die alle mehr oder weniger wichtig sind, von denen Sie aber keine wirklich interessieren muss. Sie dienen alle dazu, die Automatismen, die Ihnen KDevelop bietet, zu unterstützen. Die eigentlichen Quellen Ihres Programms finden Sie in einem Unterverzeichnis, das denselben Namen wie das Projektverzeichnis trägt. Auch die ausführbare Datei wird dorthin erzeugt.

KDevelop setzt vollkommen auf offenen Standards auf. Wenn Sie also der Ansicht sind, dass dieses Werkzeug doch nicht das richtige für Sie ist, können Sie mit den generierten Dateien auch problemlos außerhalb von KDevelop weiterarbeiten. Mehr als make (siehe Seite [*]) brauchen Sie dafür im Allgemeinen nicht.

Vorhandene Projekte mit KDevelop verwalten

Sie können aber auch Projekte, zu denen Sie schon ein Makefile erstellt haben, mit KDevelop bearbeiten. In diesem Fäll lässt KDevelop Ihr Makefile auch völlig unangetastet, so dass keine Ihrer Eintragungen verloren geht. Umgekehrt bedeutet das natürlich auch, dass Sie auf einige Bequemlichkeit im Hinblick auf Einstellung der Projektoptionen verzichten müssen.

Um ein Projekt unter die Fittiche von KDevelop zu stellen, gehen Sie folgendermaßen vor:

  1. Starten Sie den Anwendungsassistenten mit PROJEKT | NEU und wählen Sie die Kategorie ANDERE | EIGENES PROJEKT.
  2. Geben Sie nun den Projektnamen und das -verzeichnis an. Ob Sie die GNU-Standarddateien dort ablegen möchten oder nicht, ist Ihren Plänen mit Ihrem Projekt überlassen. Achtung: Das Verzeichnis darf dabei noch nicht existieren! Legen Sie es also an anderer Stelle beziehungsweise parallel zu Ihrem bestehenden Arbeitsverzeichnis an. Wir werden dann in einem späteren Schritt Ihre vorhandenen Dateien in das neue Verzeichnis kopieren.
  3. Wenn Sie möchten, können Sie Ihr neu erzeugtes Projekt unter die Verwaltung von CVS stellen. Das ist zwar nicht zwingend erforderlich, jedoch oft hilfreich und daher empfehlenswert.
  4. Sie können nun gleich auf ERSTELLEN klicken. Die ausgelassenen Seiten des Assistenten mit den Vorlagen für die Köpfe der Projektdateien übernehmen Sie damit einfach. Im Vergleich mit den umfangreichen Tätigkeiten, die KDevelop bei einem KDE-Projekt startet, ist der Prozess für ein solches Projekt extrem kurz. Das soll er ja auch sein, schließlich haben Sie bereits einiges für dieses Projekt fertig gestellt.
  5. Schließen Sie den Assistenten mit einem Klick auf BEENDEN.
  6. Gehen Sie nun zu PROJEKT | VORHANDENE DATEI(EN) HINZUFÜGEN (siehe Abbildung [*]Fig:KDevel-Addproj). Mit Hilfe des Ordner-Symbols öffnet sich für die Kategorie QUELLDATEI(EN) ein Auswahldialog. Wählen Sie dort die Dateien, die bisher zu Ihrem Projekt gehört haben und die Sie künftig mit KDevelop bearbeiten möchten; im Allgemeinen sind dies Header- und Implementierungsdateien sowie eine Make-Datei. Sie können in diesem Dialog mehrere Dateien auf einmal auswählen, wenn Sie beim Anklicken die Taste Strg gedrückt halten.
  7. Schließen Sie den Dialog zum Hinzufügen von Dateien mit OK. Nun kopiert KDevelop die von Ihnen angegebenen Dateien in ein Unterverzeichnis Ihres Projekts, das denselben Namen wie das Projekt selbst trägt (allerdings in Kleinbuchstaben). Zum Beispiel können die Quellen zum Projekt Datum im Verzeichnis /home/thomas/work/Datum/datum liegen.
  8. Das letzte Problem ist das Makefile. Normalerweise enthält das Projektverzeichnis selbst ein Makefile, das dann auf das eigentliche Makefile im Unterverzeichnis mit den Programmdateien verweist. Bei einem von Ihnen selbst angelegten Projekt ist das nicht der Fall. Hier haben Sie ja nur ein Makefile, das Sie ins Unterverzeichnis kopiert haben. Um dieses Problem zu lösen, öffnen Sie mit F7 den Dialog PROJEKT-OPTIONEN, gehen dort zur Seite MAKE-OPTIONEN und geben bei MAKE AUSFÜHREN IN den Namen des Unterverzeichnisses ein. Im Beispiel von oben ist dies datum/.

Figure: Sie können mehrere Dateien auf einmal zu einem Projekt hinzufügen.



\resizebox*{!}{!}{\includegraphics{images/kdev-addproj.eps}}

Nach diesen Schritten können Sie Ihr Projekt mit KDevelop übersetzen, bei Fehlern an die richtigen Stellen im Quelltext springen und den Debugger verwenden.

Zwei \resizebox{10mm}{!}{\includegraphics{images/vorsicht.eps}} Aspekte sollten Sie jedoch von vornherein bei den Makefiles der Projekte beachten, die Sie später mit KDevelop bearbeiten wollen:

Außerdem kann es Probleme beim Aufruf des Debuggers geben, der die ausführbare Datei nicht finden kann. In diesem Fall wählen Sie mit dem Menüpunkt DEBUGGEN | START (SONSTIGE) | WEITERE AUSFÜHRBARE DATEI DEBUGGEN die in Ihrem Projekt erzeugte Datei aus. Dann lässt sich der Debugger problemlos starten. Eine andere Möglichkeit ist, in den PROJEKT-OPTIONEN unter AUSFÜHRBARE DATEI den richtigen Dateinamen anzugeben.

Hilfepunkte können Sie übrigens ganz einfach setzen, indem Sie für die jeweilige Zeile einmal auf den linken grauen Rand des Editorfensters klicken. Um sie zu bearbeiten, benutzen Sie das Kontextmenü des jeweiligen Haltepunktes im Ausgabefenster (normalerweise unterhalb des Editors, Karteireiter HALTEPUNKTE). Weitere Debugger-Kommandos können Sie über das Menü DEBUGGEN oder die entsprechenden Schaltflächen in der Werkzeugleiste geben.


KDE-Anwendungen mit KDevelop entwickeln

Die eigentliche Domäne von KDevelop ist wie gesagt die Entwicklung von Anwendungen für die grafische Benutzeroberfläche KDE. Diese baut auf der Bibliothek Qt von Trolltech auf, so dass man auch von Qt-Anwendungen sprechen kann. Diese Klassenbibliothek ist mit mehr als 400 Klassen in über 800 Dateien sehr umfangreich; ich kann sie daher natürlich hier nicht im Detail behandeln. Wenn ich Ihr Interesse am Schreiben von KDE-Anwendungen wecken konnte, sollten Sie Ihr Wissen mit anderen Büchern wie [] oder [] vertiefen.

Dennoch möchte ich in diesem Abschnitt versuchen, Ihnen den Start in die Welt der KDE-Anwendungen etwas zu erleichtern. Schritt für Schritt werden wir eine kleine Anwendung entwickeln, die Ihnen insbesondere die dafür nötigen Handgriffe mit KDevelop nahe bringen will.

Beispiel: Berechnung des Body-Mass-Index

Gerade Softwareentwickler üben ja eine überwiegend sitzende Tätigkeit mit wenig Bewegung aus. Wenn sie dann noch zu einer Fehlernährung (etwa in Form der legendären Pizzas mit Kaffee) neigen, führt dies nicht selten zu Übergewicht. Aber wann kann man eigentlich von Übergewicht sprechen? Nur die Körpergröße minus 100 in Kilogramm als Richtschnur zu nehmen, entspricht nicht mehr dem Stand der Wissenschaft. Die Weltgesundheitsorganisation WHO empfiehlt daher den so genannten Body-Mass-Index (BMI) als Kriterium. Dieser berechnet sich als

\begin{displaymath}BMI = \frac{\mbox{Gewicht} [kg]}{(\mbox{K\uml orpergr\uml o\3e} [m])^2}\end{displaymath}

Werte zwischen 18.5 und 25 gelten dabei als Normalgewicht.

Unpraktisch am BMI ist, dass er sich nicht so leicht im Kopf errechnen lässt. Daher wollen wir in diesem Abschnitt ein Programm entwickeln, das nach der Eingabe von Größe und Gewicht den BMI bestimmt und noch ein paar Aussagen zu Risiken von Übergewicht macht. Letztere sollen abhängig vom Geschlecht der Person sein, so dass wir auch noch dafür eine Eingabemöglichkeit vorsehen müssen. Die Oberfläche der Anwendung soll also ungefähr wie in Abbildung [*] aussehen.

Figure: Unsere Anwendung soll Geschlecht, Größe und Gewicht fragen und daraus den BMI berechnen.
\resizebox*{!}{!}{\includegraphics{images/kdev-bmi.eps}}

Die dahinter stehende Logik ist sehr einfach: Nach Eingabe der Daten und einem Klick auf die Schaltfläche AUSWERTUNG STARTEN wird die Plausibilität der Daten geprüft (um unsinnige Ergebnisse bei Eingabefehlern zu vermeiden), der Wert berechnet und anschließend zusammen mit einem Kommentar angezeigt.


Signale und Schlitze

Heutzutage entwickelt man grafische Benutzeroberflächen (auf Englisch Graphical User Interfaces, GUIs) fast nur noch mit Hilfe von Klassenbibliotheken. Es ist einfach viel zu umständlich, jeden Strich einer Dialogbox selbst zeichnen zu müssen. Da aber Qt wie jede Klassenbibliothek ihre eigene Philosophie und eigene Paradigmen hat, müssen wir uns vor der eigentlichen Programmierung ein paar zentrale Begriffe ansehen, die für das Verständnis des Aufbaus von Qt-Anwendungen notwendig sind.

Grafische Benutzeroberflächen arbeiten in mancherlei Hinsicht deutlich anders als alle sonstigen Anwendungsprogramme. Bei unseren bisherigen Programmen gab es meistens eine mehr oder weniger klare Linie, die von der Eingabe der Daten über die Verarbeitung bis zur Ausgabe geführt hat. Bei der Benutzeroberfläche gibt es eine solche Linie nicht.

Eine solches Programm muss sich stets dem Willen des Benutzers unterwerfen. Das bedeutet praktisch, dass es so lange warten muss, bis der Benutzer eine bestimmte Aktion macht, und dann darauf prompt zu reagieren hat. Die Reaktion kann dabei sehr unterschiedlicher Art sein. Bei einem Klick auf eine Schaltfläche SCHLIESSEN soll sich beispielsweise ein Fenster schließen, bei der Selektion eines bestimmten Werts in einer Liste sollen nur die Inhalte einiger anderer Elemente aktualisert werden usw. Wir haben es also mit einer ereignisgesteuerten Programmierung zu tun. Das bedeutet, dass bei den Steuerelementen bestimmte Ereignisse eintreten (entweder durch die Interaktion des Benutzers oder intern als Folge eines anderen Ereignisses) und als Reaktion darauf entsprechende Behandlungsroutinen aufgerufen und abgearbeitet werden.

Im Sinne der Objektorientierung - denn in Qt sind alle Steuerelemente echte C++-Objekte - heißt das, dass ein Objekt ein Ereignis signalisiert, wenn es seinen Zustand so geändert hat, dass dies für andere von Interesse sein könnte. Wer auf dieses Ereignis reagiert und was daraufhin getan wird, ist für das Objekt selbst nicht von Bedeutung. Umgekehrt kann eine Behandlungsroutine auch durch verschiedene Arten von Ereignissen ausgelöst werden. Beispielsweise soll ja beim Klick auf ein Symbol der Werkzeugleiste und bei der Auswahl des entsprechenden Menüpunktes jeweils dieselbe Aktion ausgeführt werden.

Solche Ereignisse bezeichnet man in Qt als Signale. Ein Objekt sendet ein Signal aus, wenn sich bei ihm etwas ändert. Wenn sich ein anderes Objekt für dieses Signal angemeldet hat, wird dessen Behandlungsroutine aufgerufen. Gibt es keinen Interessenten, passiert auch nichts. Ein Signal ist eine Methode der Klasse, die auch Parameter haben kann. Zudem kann das aussendende Objekt noch zusätzliche Informationen über das Ereignis mitgeben. Viele Klassen in Qt haben bereits Signale vordefiniert; durch Ableiten können Sie aber jederzeit neue hinzufügen.

Eine Methode zum Behandeln von Signalen bezeichnet man bei Qt als Slot. Ein Slot entspricht in der Signatur dem Ereignis, auf das er reagieren soll (er darf genau genommen aber auch weniger Parameter haben). Er wird dann aufgerufen, wenn das Ereignis eintritt, mit dem er verbunden ist. Natürlich können Sie eine Slot-Methode auch wie jede andere C++-Methode aufrufen. Meistens wird man solche Methoden als public slots deklarieren, damit auch die Signale anderer Objekte damit verbunden werden können. Es ist aber möglich, diese auf protected slots oder gar private slots einzuschränken. Jedes Qt-Objekt, das von einem Typ ist, der von QObject abgeleitet ist (wie das alle grafischen Steuerelemente sind), kann Signale und Slots beinhalten.

Wie findet nun das Signal seinen Slot? Anders als bei anderen GUI-Bibliotheken setzt Qt hierbei auf eine sehr lose Kopplung. Die Verbindung ist weder Teil des aussendenden noch des empfangenden Objekts, sondern wird separat festgelegt. Dadurch ist es aber sehr bequem möglich, einem Signal verschiedene Slots zuzuordnen oder aber einen Slot zur Behandlung mehrerer Signale zu verwenden. Die Objekte selbst wissen darüber nichts.

Wenn Sie sich jetzt fragen, ob Sie das alles auch so selbst programmieren müssen, kann ich Sie beruhigen. Der Qt-Designer, mit dem wir später die grafischen Elemente entwerfen werden, unterstützt Sie beim Setzen von Slots und beim Zuordnen zu Signalen durch entsprechende Dialoge. Mit ein paar Klicks sind die entsprechenden Verbindungen hergestellt. Der Rest wird automatisch erledigt.

Trotzdem möchte ich Ihnen zur Illustration etwas vom generierten Code zeigen, damit Sie das Konzept besser verstehen. Unser Dialog aus Abbildung [*] beinhaltet ein Objekt namens pbEval vom Typ QPushButton. Diese Klasse hat keine eigenen Signale definiert; sie stehen in ihrer Basisklasse QButton. Signale deklariert man mit Hilfe des speziellen Schlüsselworts signals, Slots mit public slot usw.

Qt-Klassen beginnt man zudem im Allgemeinen mit dem Makro Q_OBJECT, das eine Reihe von Standardmethoden deklariert. Die Klasse QButton sieht damit etwa wie folgt aus (ich habe allerdings viele Bestandteile gelöscht, um Ihnen die Übersicht zu erleichtern):

class QButton : public QWidget

{

    Q_OBJECT

 

public:

    QButton( QWidget* parent=0, 

             const char* name=0, WFlags f=0 );

    ~QButton();

 

    QString text() const;

    virtual void setText( const QString &);

 

signals:

    void        pressed();

    void        released();

    void        clicked();

 

protected:

    virtual void drawButton( QPainter * );

 

    void        keyPressEvent( QKeyEvent *);

    void        keyReleaseEvent( QKeyEvent *);

 

private slots:

    void        animateTimeout();

    void        autoRepeatTimeout();

 

private:

    QString     btext;

 

    friend class QButtonGroup;

 

// ...

};

Das Signal kommt also direkt vom Button; den Slot ordnen wir dem Formular zu (also der Klasse für das Hauptfenster), da über dieses die gesamte Interaktion abgewickelt werden soll. Meist ist es sinnvoll, Slots, die Signale von Steuerelementen auf einem Formular behandeln sollen, innerhalb der Formularklasse zu definieren. Wir fügen also mit dem entsprechenden Hilfsmittel des Designers unserem Formular BmiMainForm einen calcSlot() zur Auswertung der Eingaben hinzu. Im Code schlägt sich das nieder als:

class BmiMainForm : public QMainWindow

{

    Q_OBJECT

 

public:

    BmiMainForm( QWidget* parent = 0, 

                 const char* name = 0, 

                 WFlags fl = WType_TopLevel );

    ~BmiMainForm();

 

    QGroupBox* GroupBox2;

    // Weitere Objekte

 

public slots:

    virtual void calcSlot();

 

};


Die Verbindung zwischen Signal und Slot wird im Konstruktor des Formulars hergestellt, wo auch alle Steuerelemente angelegt und konfiguriert werden.

BmiMainForm::BmiMainForm( QWidget* parent,  

                          const char* name, WFlags fl )

    : QMainWindow( parent, name, fl )

{

    // Initialisiere die Steuerelemente

    // ...

 

    // Verbinde Signale und Slots 

    connect( pbEval, SIGNAL( clicked() ), 

             this, SLOT( calcSlot() ) );

}


Bei den Qt-spezifischen Schlüsselwörten wie signals handelt es sich nicht um Spracherweiterungen von C++, sondern nur um sehr geschickt angelegte Makros. Aus Gründen der Flexibilität und Portabilität setzt Qt hierbei auf einen zusätzlichen Präprozessor, den Meta-Object-Compiler moc. Dieser MOC wird auf alle Header-Dateien angewendet, die Klassen mit einer Q_OBJECT-Deklaration enthalten. Er löst die Makros auf und erzeugt daraus Standard-C++-Code. Die daraus entstandenen Dateien werden mit den anderen Projektdateien übersetzt und zum Gesamtprogramm verlinkt. Wenn Sie mit Entwicklungsumgebungen wie KDevelop arbeiten, bleiben diese Vorgänge weitgehend vor Ihnen verborgen - alles läuft automatisch ab. Sie merken nur, dass sich am Ende in Ihrem Quellverzeichnis ein paar mehr C++-Dateien befinden, als Sie selbst geschrieben haben.

Der Qt-Designer

In diesem Abschnitt möchte ich Ihnen erklären, wie Sie eine grafische Benutzerschnittstelle für Qt-Programme, also Formulare und Dialoge, entwerfen. Dazu liefert Qt nämlich ein eigenes Werkzeug mit, den Qt-Designer. Er kennt sehr viele Steuerelemente von Qt und KDE und erlaubt Ihnen, diese mit der Maus auf Formularen anzuordnen und ihre Eigenschaften festzulegen (Abbildung [*]).

Figure: Der Qt-Designer erlaubt Ihnen, Benutzerschnittstellen mit ein paar Mausklicks zu entwerfen.

\resizebox*{!}{!}{\includegraphics{images/qtdesigner.eps}}

Wenn Sie schon mit anderen Werkzeugen wie Visual Basic oder Delphi gearbeitet haben, wird Ihnen das Konzept bekannt vorkommen: eine Werkzeugleiste mit Komponenten, ein Editor für Eigenschaften und Ereignisbehandlungsroutinen sowie Möglichkeiten zur Formatierung und Vorschau.

Um die Oberfläche für ein Programm wie in unserem Beispiel mit KDevelop und dem Qt-Designer zu entwerfen, gehen Sie folgendermaßen vor:

  1. Starten Sie zunächst den Anwendungsassistenten von KDevelop und lassen Sie sich von ihm ein Projekt vom Typ KDE-MINI erzeugen. Ich habe das Projekt Bmi genannt.
  2. Wählen Sie DATEI | NEU und selektieren Sie dort QT DESIGNER-DATEI. Geben Sie im Eingabefeld rechts oben einen Namen für diese Datei an, zum Beispiel bmidlg.ui.
  3. Wenn Sie nun gefragt werden: Möchten Sie die Datei als ASCII-Datei laden?, so klicken Sie auf NEIN. Wir möchten ja nicht die Benutzerschnittstelle mit dem Editor, sondern mit dem Qt-Designer erzeugen.
  4. Dieser startet nun als selbstständiges Programm und zeigt Ihnen seine eigene Oberfläche (siehe Abbildung [*]) und auch gleich einen eigenen Assistenten.
  5. Wählen Sie aus dem NEW-Dialog den Eintrag MAIN WINDOW.
  6. Da wir auf ein Menü und eine Werkzeugleiste verzichten wollen, löschen Sie nun im MAIN WINDOW WIZARD alle Kontrollkästchen, so dass keines mehr angekreuzt ist. Schließen Sie den Wizard mit FINISH ab.
  7. Als Nächstes sollten wir den Dialog abspeichern. KDevelop startet zwar den Qt-Designer, übergibt ihm aber bei neu zu erzeugenden Dateien nicht den Namen. Wählen Sie FILE | SAVE und speichern Sie die Datei unter dem Namen, den Sie bereits in KDevelop verwendet haben, also etwa bmidlg.ui. Auf diese Weise müssen Sie die Datei nicht später nochmals zu Ihrem Projekt hinzufügen. Bestätigen Sie das Überschreiben der Datei.

Nun geht es an die Gestaltung des Formulars. Bevor Sie sich für diese Aufgabe an den Rechner setzen, sollten Sie bereits eine möglichst konkrete Vorstellung davon haben, welche Bedienelemente darauf vorkommen und wie diese zueinander angeordnet werden sollen. Achten Sie darauf, dass Ihre Dialoge nicht zu überladen sind, denn dies kann für den Benutzer sehr schnell unübersichtlich und undurchschaubar werden. Wenn Sie mehr Steuerelemente benötigen, als auf Ihr Formular passen, verwenden Sie besser ein TabWidget, mit dem sich zwischen verschiedenen Teil-Formularen blättern lässt.

Für das Fenster aus Abbildung [*] (Seite [*]) benötigen wir aber nur einige wenige grafische Elemente. Ich möchte Ihnen hier nicht jeden Schritt im Detail erläutern, sondern nur ein paar Eckpunkte geben, anhand derer Sie ein solches Formular sicher schnell selbst erstellen können - wenn Sie das möchten. Dabei verwende ich sprachlich vorwiegend die englischen Ausdrücke für Ihre bessere Orientierung im Qt-Designer; verzeihen Sie mir also das etwas zu anglophile Deutsch hier.

Aufgrund der fixierten Größe des Formulars benötigen wir eigentlich keine Hilfsmittel wie Spacer und Layoutrahmen. Versuchen Sie aber trotzdem schon bei einfachen Formularen wie hier diese Funktionen einzusetzen, damit Sie ein Gefühl für deren Wirkungsweise bekommen. Es handelt sich dabei um sehr effektive Gestaltungsmittel für die flexible Anpassung an Veränderungen der Fenstergröße. Generell sollten Sie dabei zunächst die horizontale Anordnung im Auge behalten, bevor Sie sich um die vertikale kümmern. Am besten ist es, wenn Sie die Wirkung von Spacern und Layout in verschiedenen Varianten mit Hilfe der PREVIEW-Funktion ausprobieren.

Nach Abschluss des Designs müssen wir noch den Klick auf die AUSWERTUNG STARTEN-Schaltfläche mit der eigentlichen Auswertung verbinden. Bei einem Qt-Formular bedeutet das, das Signal clicked mit einem entsprechenden Slot zu verbinden (siehe auch Seite [*]). Um eine solche Verbindung zu erstellen, müssen Sie zunächst in den entsprechenden Modus wechseln, zum Beispiel mit TOOLS | CONNECT SIGNALS/SLOTS oder einfach mit F3. Dadurch wird der Mauszeiger zu einem Kreuz. Eine Verbindung stellen Sie her, indem Sie auf das signalerzeugende Steuerelement (bei uns der PushButton) klicken und die nun erscheinende Linie zum Widget ziehen, das den Slot dafür beinhalten soll. Beim Herumfahren mit der Maus werden Sie sehen, dass Letzteres durch einen violetten Rahmen markiert wird. Bei Dialog- und Hauptprogrammfenstern definiert man die Slots für die Reaktionen auf Schaltflächen und Ähnliches im Allgemeinem in der Formularklasse. Das wollen wir auch hier tun. Ziehen Sie also die Verbindungslinie über die freie Fläche des Formulars aus diesem hinaus und lassen Sie die linke Maustaste dann erst los.

Figure: Verbinden Sie die Signale mit den Slots in diesem Dialog.

\resizebox*{0.8\columnwidth}{!}{\includegraphics{images/qtdes-editconnection.eps}}

Nun öffnet sich ein Dialog wie in Abbildung [*], mit dem Sie die Details dieser Verbindung festlegen können.

Wir wollen eines der vordefinierten Signale des Pushbuttons verwenden, nämlich clicked(). Dieses wird ausgelöst, wenn der Benutzer die Schaltfläche einmal anklickt. Um aber flexibel zu bleiben, wollen wir zur Behandlung selbst einen Slot definieren. Wählen Sie dazu zunächst clicked() als das zu behandelnde Signal aus. Mit einem weiteren Klick auf EDIT SLOTS öffnen Sie einen zusätzlichen Dialog, der Ihnen alle definierten Slots der jeweiligen Formular- oder Steuerelementklasse anzeigt. Im Augenblick ist die Liste noch leer. Mit NEW SLOT fügen Sie einen neuen Slot hinzu, dem Sie im Eingabefeld SLOT den Namen calcSlot() geben können (siehe Abbildung [*]). Die übrigen Einstellungen können Sie auf den Vorgabewerten belassen. Wenn Sie nun dieses Fenster mit OK schließen, erscheint der neue Slot in der Liste oben rechts im EDIT CONNECTIONS-Dialog.

Figure: Hier können Sie neue Slots für eine Widget-Klasse anlegen.

\resizebox*{0.8\columnwidth}{!}{\includegraphics{images/qtdes-editslots.eps}}

Nun müssen Sie nur noch zuerst auf clicked() in der linken Liste und dann auf calcSlot() in der rechten Liste klicken - schon ist eine Verbindung des Signals mit dem Slot hergestellt und taucht auch sofort in der Liste der Connections im unteren Bereich des Fensters auf (wie in Abbildung [*]).

Damit können wir diesen Dialog schließen und sind mit dem Design unserer GUI fertig. Bei komplexeren Anwendungen werden Sie sicher weitere Steuerelemente haben, mehrere Signale behandeln und umfangreicherere Slots definieren - die Vorgehensweise, die ich Ihnen anhand dieses simplen Beispiels gezeigt habe, bleibt aber die gleiche.

Implementierung der Anwendung

Als Nächstes müssen wir die gerade entworfene Benutzerschnittstelle mit dem bereits vorhandenen Gerüst unserer Anwendung zusammenbringen. Fügen Sie zunächst bei den #include-Anweisungen die folgende Zeile ein:

#include "bmidlg.h"

Außerdem ist es erforderlich, dass die Klasse Bmi von BmiMainForm abgeleitet ist und nicht von QWidget.

class Bmi : public BmiMainForm

Schließlich muss noch die Deklaration für den Slot eingefügt werden, so dass die ganze Klasse Bmi dann die folgende Form hat:

#include <kapp.h>

#include <qwidget.h>

#include "bmidlg.h"

 

/** Bmi is the base class of the project */

class Bmi : public BmiMainForm

{

  Q_OBJECT 

  public:

    /** construtor */

    Bmi(QWidget* parent=0, const char *name=0);

    /** destructor */

    ~Bmi();

 

public:

    virtual void calcSlot();

};


Da unsere Anwendung recht simpel ist, sind wir nun bereits beim letzten Arbeitsschritt angelangt: der Implementierung von calcSlot(). Hier müssen wir erstmals von einem Programm aus direkt auf die Steuerelemente auf dem Formular zugreifen, denn wir wollen die Eingaben des Benutzers verarbeiten und Ausgaben erzeugen. Dazu ein paar grundlegende Bemerkungen:

Mit diesem Wissen im Hinterkopf ist die Fertigstellung der Implementierung unseres Beispielprogramms nicht mehr schwierig. Zunächst wandeln wir wie gerade beschrieben die Eingaben in float-Zahlen um und prüfen deren Plausibilität:

void Bmi::calcSlot()

{

  float height = (leHeight->text()).toFloat();

  float weight = (leWeight->text()).toFloat();

 

  if (height < 50 || height > 300)

  {

Bei einer Körpergröße von weniger als 50 cm oder mehr als 300 cm gehen wir von einem Eingabefehler aus (beispielsweise eine Eingabe in m). In diesem Fall weisen wir den Benutzer über eine QMessageBox, ein Nachrichtenfenster, darauf hin.

    QMessageBox mb("Unzulässiger Wert",

      "Bitte geben Sie die Größe in cm an!",

      QMessageBox::Warning,

      QMessageBox::Ok | QMessageBox::Default,

      QMessageBox::NoButton,

      QMessageBox::NoButton);

 

    mb.exec();

 

    return;

  }

Analog wollen wir ein Gewicht von unter 20 kg und über 1000 kg nicht mehr als gültige Eingabe akzeptieren. Der Programmcode ist dabei fast der gleiche wie oben, so dass ich hier auf einen Abdruck verzichte.

Nun können wir den BMI berechnen und in das dafür vorgesehene Label schreiben. Dabei leistet die Methode QString::sprintf() gute Dienste, die für die formatierte Ausgabe dasselbe Format wie die C-Funktion sprintf() akzeptiert. In diesem Fall wollen wir uns auf eine Nachkommastelle beschränken.

  height /= 100;

  float bmi = weight/(height*height);

  

  QString s;

  s.sprintf("Ihr BMI ist %.1f", bmi);

  lBmi->setText(s);

Als Letztes wollen wir noch einen Hinweistext über Gesundheitsgefahren durch Übergewicht in unserem QTextEdit-Feld in Abhängigkeit vom Geschlecht ausgeben. Die verschachtelten if-Anweisungen sind programmiertechnisch nicht so interessant, so dass es genügen sollte, wenn ich Ihnen hier die ersten Zeilen vorstelle:

  if (bmi < 18.5)

  {

    s = "Sie haben Untergewicht.";

  }

  else

     if (bmi < 25)

     {

       s = "Sie haben Normalgewicht. ";

       if (rbMale->isChecked())

         s += "Keinerlei Risiko.";

       else

       {

         s += "Keine Gefahr für Diabetes und Herz";

         s += "krankheiten, außer bei zu viel Fett.";

       }

     }

     else

       // Weitere Fallunterscheidungen

       // ...

Diesen Info-Text geben wir nun noch aus und sind damit am Ende dieser Methode.

  teTextbox->setText(s);

  return;

}


Probleme beim Übersetzen der Anwendung

Jetzt \resizebox{10mm}{!}{\includegraphics{images/vorsicht.eps}} ist es an der Zeit, dass wir unsere Anwendung übersetzen. Dies sollte eigentlich problemlos möglich sein. Bei der Version 2.1 von KDevelop zu KDE 3.0, die beide auf Qt 3.0 aufbauen, sind bei mir jedoch einige Schwierigkeiten aufgetreten, vor denen ich Sie gerne bewahren möchte.

Zunächst sollten Sie sicherstellen, dass Sie für die Kompilierung den GCC 2.95 verwenden. Qt ist noch nicht auf den GCC 3.0 ausgelegt, so dass es Probleme beim Linken der Bibliotheken geben kann.

Daneben scheint es noch ein paar Inkonsistenzen beim Konfigurationsskript zu geben, das die Make-Dateien für die KDevelop-Projekte erzeugt. Wenn Sie KDE nicht - wie es offenbar der Vorgabewert ist - im Pfad /usr/local/kde installieren, sondern an einer anderen Stelle (SuSE legt es beispielsweise unter /opt/kde3 ab), müssen Sie den prefix-Eintrag in der Make-Datei ändern. Gehen Sie dazu in KDevelop in die Liste der Dateien, öffnen Sie den Zweig mit den eigentlichen Quelldateien (im Beispiel ist das bmi/) und laden Sie das dort enthaltene Makefile in den Editor. Bereits in der sechsten Zeile wird das Makro prefix definiert; Sie sollten es auf den Pfad setzen, unter dem KDE 3 in Ihrem Dateisystem zu finden ist, beispielsweise

prefix = /opt/kde3

Wenn Sie Ihr Programm nun mit F8 übersetzen, könnte noch eine Schwierigkeit auftreten. Beim Kompilieren des Codes, der automatisch aus den Dialogdefinitionen erzeugt wurde, die wir mit Qt-Designer erstellt haben, treten Fehlermeldungen auf wie:

In file included from bmidlg.cpp:164:

bmidlg.moc:29: syntax error before `('

bmidlg.moc:34: no `void BmiMainForm::initMetaObject()' 

member function declared in class `BmiMainForm'

Etwas durchsichtiger ist es, wenn die Meldung lautet:

gmake[2]: /usr/lib/qt/bin/moc: Command not found

In beiden Fällen liegt es daran, dass in der Make-Datei der falsche Pfad für die Qt-Installation eingetragen ist, insbesondere für den Meta-Object-Compiler moc (und darüber hinaus noch ein anderer als der unter OPTIONEN | EINRICHTUNG | PFAD gesetzte!). Überprüfen Sie daher, wo bei Ihnen Qt und der moc liegen und passen Sie den Eintrag MOC in der oben genannten Make-Datei Ihres Projekts entsprechend an, zum Beispiel auf

MOC = /usr/lib/qt3/bin/moc

Mit diesen Änderungen sollte sich Ihre Anwendung erfolgreich übersetzen lassen. Beachten Sie aber, dass Sie die Änderungen am Makefile jedes Mal wiederholen müssen, wenn Sie dieses neu erzeugen.

Fazit

Ihr Anwendungsfenster sollte nun ungefähr so aussehen wie in Abbildung [*] (Seite [*]). Wie hoch ist Ihr eigener BMI? Liegt er über 25, sollten Sie vielleicht dieses Buch mal für eine Stunde weglegen und statt zu lesen (oder programmieren) lieber joggen gehen ...

Sie sollten aber auf jeden Fall anhand dieses Beispiels die grundsätzliche Vorgehensweise beim Erstellen einer KDE/Qt-Anwendung mit KDevelop erkannt haben. Wenn Ihnen dann der Umgang mit der IDE keine Probleme mehr bereitet, können Sie sich voll und ganz auf die Entwicklung von Dialogen und komplexeren Applikationen mit den verschiedensten Qt-Objekten konzentrieren. Mit weiteren Büchern wie [] oder [] können Sie bei Interesse und Bedarf noch viel über Qt erfahren.

Zusammenfassung

In diesem Abschnitt habe ich Ihnen mit KDevelop die derzeit ausgereifteste integrierte Entwicklungsumgebung vorgestellt, die unter Linux als Open-Source-Anwendung verfügbar ist. Als wichtigste Eindrücke sollten bei Ihnen folgende Aspekte erhalten geblieben sein:

Alles in allem ist KDevelop eine umfangreiche und stabile Entwicklungsumgebung, die fast alles liefert, was man als Programmierer benötigt. Sie ist damit sowohl für den Anfänger als auch für den Profi sehr empfehlenswert. Da die Entwicklung daran aber immer noch mit Nachdruck weitergeht, werden wir sicher noch viele interessante neue Funktionselemente im Lauf der Zeit zu sehen bekommen.


Source Code Engineering mit SNiFF+

Eine integrierte Entwicklungsumgebung mit vielerlei Vorzügen, ist SNiFF+ von Windriver (vormals von TakeFive). Sie hat eine gute Teamunterstützung, ist für vielerlei Plattformen und eine Reihe von Programmiersprachen (C/C++, Java, Fortran, Cobol, Python, Perl etc.) verfügbar und kann auch wirklich große Projekte effizient verwalten. Der einzige Nachteil war lange Zeit der relativ hohe Preis. Doch da gab es eine gute Nachricht - wenigstens für eine Zeit lang. Die Penguin Edition der Version 3.2, die die C++-Entwicklung unter Linux unterstützt, war kostenfrei erhältlich. Mittlerweile sah Windriver dadurch aber das Geschäft mit der kommerziellen Version beeinträchtigt und hat diese freie Version vom Markt genommen. SNiFF+ 4.x gibt es nur noch als kostenpflichtiges Paket.

Vielleicht haben Sie aber Glück und bei Ihrer Linux-Distribution befindet sich noch ein SNiFF-Pinguin. Wenn nicht, finden Sie alles Nötige auf beiliegender CD-ROM, da WindRiver dem dpunkt.verlag für dieses Buch die entsprechenden Rechte gewährt hat.

Projekte in SNiFF+

Projekte sind in SNiFF+ hierarchisch organisiert. Das bedeutet, dass jedes Projekt ein oder mehrere Unterprojekte haben kann, von denen es abhängt. Auch diese können wieder eigene Unterprojekte haben und so weiter. Dabei können Sie frei einstellen, welches Ergebnis ein Unterprojekt nach oben liefern soll: seine Objektdateien, eine Bibliothek oder eine eigene ausführbare Datei. SNiFF+ legt fest, dass ein Projekt denselben Namen tragen muss wie das Verzeichnis, in dem es sich befindet. Das ist im Allgemeinen keine Einschränkung, sondern fördert die Einfachheit und Übersichtlichkeit eines Projekts. Zusätzlich müssen alle verschiedenen Projekte in einer Hierarchie auch verschiedene Namen tragen (obwohl sie für das Dateisystem und den Compiler eigentlich durch ihren Pfad eindeutig bestimmt sind). Findet SNiFF+ beim Analysieren eines bestehenden Projekts ein solches Unterverzeichnis zum wiederholten Mal, so wird der Projektname aus dem Verzeichnisnamen des darüber liegenden Ordners und des aktuellen zusammengesetzt. In net/src und img/src werden beispielsweise net_src.proj und img_src.proj angelegt.

Als Beispiel betrachte ich in diesem Abschnitt vorwiegend die freie Bibliothek Qt, da unsere bisherigen Beispiele doch recht klein waren und die Funktionalität von SNiFF+ daher nicht so gut veranschaulichen konnten. Qt ist eine vorbildlich aufgebaute C++-Bibliothek, die vor allem als Basis für die Benutzeroberfläche KDE große Verbreitung erreicht hat. Die aktuelle Version erhalten Sie unter www.troll.no. Die über 420 Klassen in mehr als 800 Dateien sind mit einfachen Werkzeugen nur äußerst schwer zu überblicken.

Abbildung [*] zeigt etwa den Projekteditor beim Browsen durch die Bibliothek. Im unteren Teil wird die Hierarchie der Projekte deutlich. Wie Sie hieran sehen, ist SNiFF+ auch gut geeignet, um bestehende Programme und Bibliotheken zu analysieren. Sie geben nur das oberste Verzeichnis an, unter dem der Code der Software steht, und alles andere wird automatisch ermittelt.

Figure: Der Projekteditor von SNiFF+ zeigt die Dateien aller ausgewählten Projekte und deren Hierarchien an.



\includegraphics{/usr/homes/thomas/cpp/cpp_linux/Text/images/sniff_proj.eps}

Die Makefiles können Sie entweder von SNiFF+ automatisch erzeugen lassen oder eigene schreiben. Es wird von Ihrem konkreten Projekt abhängen, für welche Möglichkeit Sie sich entscheiden.

Überblick über die SNiFF-Umgebung

Der etwas merkwürdige Name dieser Software kommt vom englischen Wort sniff, also schnüffeln. Als eine ihrer Hauptaufgaben versteht sie nämlich das selbstständige Analysieren von Quellcode. Dazu beinhaltet SNiFF+ eine Reihe von Werkzeugen, die ich kurz vorstellen will.

Das Besondere an SNiFF+ ist, dass es die für die Programmentwicklung grundlegenden Werkzeuge wie Compiler oder Debugger nicht selbst enthält, sondern lediglich die vorhandenen aufruft. Unter Linux ist das als Compiler standardmäßig der GCC; aber auch andere Compiler (mit ähnlichen Optionen) lassen sich benutzen. Überhaupt ist SNiFF+ im Hinblick auf die Integration von anderen Werkzeugen sehr vielseitig. Fast jedes Werkzeug lässt sich in die IDE integrieren. Sie können eigene Menüpunkte hinzufügen und komplette Abläufe umstellen. Die Programmierschnittstelle in Python macht SNiFF+ besonders offen; diese Schnittstelle wird auch intern benutzt, wobei die entsprechenden Skripte im Quelltext mitgeliefert werden und daher ebenfalls angepasst werden können - falls Sie das wollen.


Der Symbolbrowser

Wenn Sie den Symbolbrowser aufrufen, erhalten Sie eine alphabetisch geordnete Liste aller Bezeichner, die im gesamten Projekt vorkommen. Durch Farben und Kürzel in der ersten Spalte werden die verschiedenen Arten unterschieden; so ist beispielsweise mit cl eine Klasse und mit mi eine inline implementierte Methode gemeint. Durch einen Doppelklick auf den Begriff wird der Editor an dessen Definitionsstelle geöffnet. Sie verwenden den Symbolbrowser vorwiegend, um einen bestimmten Bezeichner, vom dem Sie nur den Namen wissen, schnell aufzufinden.


Der Klassenbrowser

Ähnlich wie der Symbolbrowser dient der Klassenbrowser dazu, alle Elemente aufzulisten - dieses Mal alle, die zu einer Klasse gehören. Es gibt wie immer verschiedene Wege, diesen Browser zu starten; sie gelangen zum Beispiel dahin, wenn Sie im Symbolbrowser eine Klasse auswählen und dann den Menüpunkt CLASS | BROWSER <Klassenname> aufrufen.

Im Klassenbrowser sehen Sie alle Bestandteile, die eine Klasse enthält; neben Datenelementen und Methoden können dies auch weitere Klassen oder Strukturen, friend-Elemente oder Konstanten sein. Auch hier können Sie wieder die Anzeige auf bestimmte Elemente wie Methoden oder Konstruktoren einschränken. Zudem können Sie im unteren Fensterbereich entscheiden, ob Sie auch die ererbten Elemente aus den Basisklassen sehen möchten oder nicht.


Der Hierarchiebrowser

Zu jedem Analysewerkzeug für objektorientierten Code gehört auch eine Anzeigemöglichkeit für Klassenhierarchien. Der in SNiFF+ integrierte Hierarchiebrowser bietet wieder einiges mehr. Neben der vollständigen Klassenhierarchie haben Sie auch die Möglichkeit, sich nur die Nachbarn einer Klasse anzeigen zu lassen, also die Basisklassen und die davon unmittelbar oder mittelbar abgeleiteten Klassen. Sie erreichen diesen Browser, indem Sie in einem der genannten Werkzeuge oder im Editor eine Klasse auswählen und entweder im Kontextmenü oder im CLASS-Menü einen der beiden folgenden Punkte wählen: SHOW <Klasse> IN ENTIRE HIERARCHY oder SHOW <Klasse> RELATIVES. Beim ersten Befehl erfahren Sie die Position dieser Klasse innerhalb der gesamten Hierarchie aller Klassen, mit dem zweiten sehen Sie nur die Vorfahren und Nachkommen. Beides kann zu verschiedenen Zwecken nützlich sein. Abbildung [*] zeigt die gesamte Hierarchie.

Figure: Die Querverbindungen in einer Klassen- hierarchie lassen zuweilen etwas längere Verbindungslinien entstehen.



\resizebox*{1\columnwidth}{!}{\includegraphics{/usr/homes/thomas/cpp/cpp_linux/Text/images/sniff_hierarchyb.eps}}




Abhängigkeiten von Header-Dateien

Ein weiteres hilfreiches Werkzeug dient der Anzeige der Abhängigkeiten zwischen Header-Dateien. Denn wenn eine Datei eine andere, diese wieder eine dritte usw. einbindet, geht die Übersicht, was in die Übersetzung eigentlich alles einfließt und was dazu nötig ist, schnell verloren. Dieser Browser ist fast genauso aufgebaut wie der für Klassenhierarchien. Sie erreichen ihn unter anderem aus dem Editor, wenn Sie einen der Menüpunkte INFO | <Dateiname> INCLUDES oder INFO | <Dateiname> IS INCLUDED-BY wählen. Im ersten Fall sehen Sie alle Header-Dateien, die diese Datei selbst einbindet, im zweiten Fall Dateien, von denen die aktuelle Datei eingebunden wird. Wollen Sie die Abhängigkeiten einer bestimmten Datei verfolgen, klicken Sie diese in der Grafik an und wählen entweder INCLUDES oder IS INCLUDED-BY aus ihrem Kontextmenü.

Editieren, Kompilieren und Debuggen

Die Kerntätigkeiten beim Programmieren sind Schreiben des Programms, Kompilieren und Debuggen - und das im Zyklus. Eine integrierte Entwicklungsumgebung muss also zuvorderst diese Abläufe unterstützen.


Editor

Der Editor von SNiFF+ ist sehr bequem zu bedienen, wenn auch am Anfang etwas gewöhnungbedürftig. Auf der rechten Seiten finden Sie ein eingebettetes Fenster, das alle Symbole dieser Datei enthält, also Klassen, Methoden und so weiter. Der Auswahlknopf darüber schränkt die Anzeige auf bestimmte Klassen ein. Die Symbole sind - wie auch schon in den anderen Browsern - durch verschiedene Textfarben voneinander abgehoben, beispielsweise Klassen grün, normale Methoden dunkelrot, inline-Methoden hellrot und Funktionen schwarz.

Figure: Der Editor in SNiFF+ dient gleichzeitig zum Navigieren.



\resizebox*{1\columnwidth}{!}{\includegraphics{/usr/homes/thomas/cpp/cpp_linux/Text/images/sniff_editor.eps}}

Viel Funktionalität ist hier über das Menü verfügbar, fast noch mehr über die jeweiligen Kontextmenüs. So können Sie beispielsweise aus der Liste der Bezeichner durch den entsprechenden Befehl sehr leicht zwischen Deklaration und Implementierung von Klassen und Methoden hin- und herspringen.

Achtung: \resizebox{10mm}{!}{\includegraphics{images/vorsicht.eps}} Die im Kontextmenü des Editors angebotenen Funktionen, zu einem beliebigen Bezeichner alle Stellen zu ermitteln, auf die sich dieser Bezeichner bezieht (zum Beispiel QTEXTBOX REFERS-TO), oder alle, wo er selbst verwendet wird (etwa QTEXTBOX IS REFERRED BY), ist in der freien Penguin-Edition von SNiFF+ nicht verfügbar. Dazu bedarf es dann doch der kommerziellen Variante.

Anfangs ungewohnt ist der Umgang mit mehreren Dateien. Anders als in den meisten Editoren (beispielsweise auch im XEmacs) ist in SNiFF+ keine Liste aller gerade offenen Dateien verfügbar. Dafür bietet das Menü HISTORY eine Liste aller zuletzt angesprungenen Codestellen, wie in einem Web-Browser. Entsprechend kommen Sie auch mit der ZURÜCK-Schaltfläche an die von Ihnen zuletzt bearbeitete beziehungsweise angesprungene Stelle; diese kann in der gleichen Datei wie Ihre aktuelle Position liegen oder in einer anderen.

Die Syntaxeinfärbung unterscheidet nach Kommentaren, Funktions- und Methodennamen, Präprozessor-Anweisungen und anderem. Sie wird nicht unmittelbar beim Tippen aktualisiert, sondern erst beim Abspeichern. Dafür ist der verwendete Parser sehr flexibel und kann auch mit unvollständigem und inkorrektem Code umgehen. Die Syntaxeinfärbung arbeitet übrigens nur für Dateien, die zum Projekt (oder einem seiner Unterprojekte) gehören. Wenn Sie eine andere C++-Datei über FILE | OPEN laden, erscheint dieses schwarz-weiß.

Die wichtigste Aktion beim Tippen ist meist das Abspeichern. Wenn Sie dafür nicht extra die Hände von der Tastatur nehmen wollen, um die Maus zu bedienen, können Sie auch mit Alt+s oder - wie beim XEmacs - mit Strg+x, Strg+s die aktuelle Datei speichern.

Andere Aktionen lassen sich mit Tastenkombinationen erledigen, die eher von Windows vertraut sind: Alt+x oder $\Uparrow$+Entf zum Ausschneiden und Alt+c oder Strg+Einfg zum Kopieren; weiterhin Alt+v oder auch $\Uparrow$+Einfg zum Einfügen, Alt+z für Rückgängig. Mit etwas Übung gehen auch diese leicht von der Hand.

Auch der Zugang zum Konfigurationsmanagement ist in den Editor integriert. Wollen Sie eine Datei, die noch eingecheckt ist, bearbeiten, weist Sie SNiFF+ darauf hin und erledigt das Auschecken. Manuell können Sie diese Dienste auch über das FILE-Menü erreichen (CHECK IN, CHECK OUT, LOCK, UNLOCK). Möchten Sie zu einer Datei allerdings die komplette Versionsgeschichte sehen, müssen Sie den Projekteditor verwenden. Wählen Sie die Datei im mittleren Feld aus und klicken Sie dann auf das Kontrollkästchen HISTORY am unteren Rand; es erscheint ein zusätzliches Fenster, in dem Sie die Liste der Revisionen erkennen können.

Kompilieren und Generieren

Das Erzeugen von Programmen lässt sich in SNiFF+ von vielerlei Orten aus aufrufen. Meist verwenden Sie dazu das Menü TARGET, aus dem Sie dann entweder RECURSIVELY MAKE PROJECT oder MAKE | ALL aufrufen. Wenn ein solcher Punkt vorhanden ist, geht auch MAKE MAIN TARGET.

Daraufhin öffnet sich ein neues Fenster, die Local Shell. In Abbildung [*] sehen diese für unser Sender/Receiver-Projekt von Seite [*].

Figure: Das Shell-Fenster stellt neben normalen Shell-Eigenschaften noch das Menü für den Zugriff auf weitere SNiFF+-Funktionen bereit.

\resizebox*{1\columnwidth}{!}{\includegraphics{/usr/homes/thomas/cpp/cpp_linux/Text/images/sniff-shell.eps}}

Die Local Shell ist eine ganz normale Shell, in der Sie auch selbst alle üblichen Befehle eingeben können. (Der Name Local Shell rührt daher, dass SNiFF+ in der größeren Version auch die verteilte Entwicklung über remote shells unterstützt.) Die Shell übernimmt zudem die Voreinstellungen des jeweiligen Benutzers; wenn Sie also üblicherweise die C-Shell verwenden, wird diese auch hier gestartet und Ihre persönlichen Einstellungen aus .cshrc werden geladen.

Ein Unterschied besteht bei der Arbeit mit der Zwischenablage. Um etwas aus diesem Fenster zu kopieren, müssen Sie es erst markieren und dann zusätzlich über EDIT | COPY oder über das Kontextmenü in die Zwischenablage bringen.

Tritt ein Fehler beim Generieren auf, klicken Sie darauf und wählen dann aus dem Kontextmenü SHOW ERROR. (Ein einfacher Doppelklick oder Ähnliches genügt leider nicht.) SNiFF+ öffnet nun die entsprechende Datei im Editor und zeigt die fehlerbehaftete Zeile an.

Für besondere Aufgaben gibt es noch den Target-Dialog, den Sie über TARGET | TARGET DIALOG öffnen können. In ihm lassen sich die Ziele separat auswählen und gezielt durch einen Klick auf MAKE erzeugen. Wenn Sie MAKE WITH DEBUG aktivieren, gibt Ihnen SNiFF+ zudem etwas mehr interne Informationen über seinen Make-Prozess aus, so dass Sie Probleme damit leichter lokalisieren können.

Der Debugger

Neben dem Generieren ist auch das Debuggen direkt aus der IDE möglich. Mit TARGET | RUN <Dateiname> können Sie das Programm in der lokalen Shell ausführen. Vor jedem Start erscheint noch ein kleines Fenster, in dem Sie mögliche Argumente für die Kommandozeile eintragen können.

Befürchten Sie Probleme in Ihrem Programm, können Sie mit TARGET | DEBUG <Dateiname> den Debugger starten. Standardmäßig verwendet SNiFF+ unter Linux den gdb (siehe Seite [*], auch zu den Begriffen und Konzepten des Debuggings). Im Debugger-Dialog (Abbildung [*]) erhalten Sie den Zugriff auf die gdb-Kommandozeile. Allerdings können Sie die meisten Befehle auch über Menüs und Buttons erreichen.

Figure: Der Debugger-Dialog lässt Eingaben auf Kommandozeilen- ebene zu.



\includegraphics{/usr/homes/thomas/cpp/cpp_linux/Text/images/sniff-debugger.eps}



Sobald Sie den Debugger aktivieren, erscheint im Editor eine zusätzliche Leiste mit Schaltflächen, über die Sie den Programmablauf steuern können. Neben RUN und CONT sind dies auch STEP, NEXT und BREAK AT (Letzteres zum Setzen eines Haltepunktes). Während des Ablaufs können Sie Ausgaben über Inhalte von Variablen über das Menü DEBUG erreichen. Die PRINT- und DISPLAY-Befehle beziehen sich dabei stets auf die aktuelle Markierung. Über die Schaltfläche Stack erfahren Sie den aktuellen Aufrufstack. Alle Ausgaben erscheinen dabei im Debugger-Dialog. Dort können Sie auch noch weitere Informationen beziehen.

Sie beenden den Debugger, indem Sie dessen Dialog schließen oder den Menüpunkt DEBUG | END DEBUG SESSION wählen.

Sie können auch den DDD unter SNiFF+ verwenden (siehe Seite [*]). Im Installationsverzeichnis gibt es einen Unterordner integrations/ddd, der die notwendigen Dateien sowie eine ausführliche Erläuterung enthält. (Diese ist unglücklicherweise im Format Microsoft Word.) Damit können Sie auch die grafischen Elemente des DDD von SNiFF+ aus einsetzen.

Zusammenfassung

In diesem Abschnitt haben Sie einen ersten Überblick über die integrierte Entwicklungsumgebung SNiFF+ bekommen. Wir haben uns dabei eine ganze Reihe von Funktionsmerkmalen angesehen:

Doch das ist bei weitem nicht alles. Es gibt also noch viel zu entdecken, was SNiFF+ bietet: Ein Konfigurationsmanagementwerkzeug, eine automatische Erzeugung von Online-Projektdokumentation und so weiter. Für ganz Entschlossene steht auch die Programmierschnittstelle in Python zur Verfügung, mit der eigene Erweiterungen geschaffen werden können.

Ein Defizit von SNiFF+ bleibt die Onlinehilfe; sie ist (trotz der verschiedentlichen HELP-Schaltflächen) keineswegs kontextsensitiv und besteht vorwiegend aus einer HTML-Version der gedruckten Handbücher. Ein Index fehlt fast völlig, eine Stichwortsuche müsste man sich mit Werkzeugen wie htDig selbst erzeugen.

Es ist schade, dass Windriver die Programmierer, die nicht einfach mal mehrere Tausend Euro für eine IDE ausgeben können, nicht mehr unterstützt. Dadurch könnte SNiFF+ wieder in die Nische zurückfallen, in der es schon einmal war. Andere IDEs wie KDevelop können sich dadurch nur umso schneller und einfacher durchsetzen.


Weitere Entwicklungsumgebungen

Auch wenn die traditionellen Programmierwerkzeuge unter Unix aus Editor, Make und Kommandozeilencompiler bestehen, sind KDevelop und SNiFF+ keineswegs die einzigen kompletten IDEs, die es unter Linux gibt. In diesem Abschnitt will ich Ihnen drei weitere vorstellen, die zumeist ähnliche Ansätze verfolgen und daher ebenso leicht erlernbar sind. Es sind dies:

Kommerziell, das heißt nicht kostenlos erhältlich, ist mittlerweile nur noch der zweite. Nach der Übernahme von Cygnus hat sich Red Hat entschlossen, den Source Navigator frei unters Volk zu bringen.


Source Navigator

Der Source Navigator bietet einen Großteil der Funktionalität von SNiFF+, ist allerdings etwas weniger bunt. Sie können ihn direkt bei Red Hat herunterladen (sources.redhat.com/sourcenav/) - oder von beiliegender CD-ROM installieren.

Die Arbeit damit findet vorwiegend in zwei Fenstern statt: Das erste ist ein Symbolbrowser, in dem wahlweise alle Dateien, Klassen, Funktionen oder Methoden des Projekts angezeigt werden können. Auch ein Filter steht zur Verfügung und die Elemente könen nach verschiedenen Kriterien sortiert werden. Wenn Sie darin eine Klasse auswählen, können Sie über einen Klick auf die entsprechende Schaltfläche der Werkzeugleiste zum Klassenbrowser, zum Hierarchiebrowser oder zum Include-Browser gelangen.

Das zweite ist eine Kombination aus Editor und verschiedenen Browsern (Abbildung [*]). Durch Reiter über dem Eingabebereich können Sie von einer Darstellung leicht zu einer anderen gelangen.

Figure: Das Hauptfenster des Source Navigator enthält neben dem Editor auch die meisten Browser.

\resizebox*{1\columnwidth}{!}{\includegraphics{/usr/homes/thomas/cpp/cpp_linux/Text/images/snav.eps}}

Zur Organisation der Projekte bietet der Source Navigator zudem einen eigenen Projekteditor, in dem sich die Abhängigkeiten in Baum-Ansicht darstellen und organisieren lassen. So wird schnell ersichtlich, welche Datei zu welchem Projekt gehört und wo Projekte ineinander greifen. Ein schönes Merkmal ist die Statistik. Durch einen Klick auf diese Schaltfläche erfahren Sie, wie viele Dateien, Klassen, Funktionen, Methoden usw. ein Projekt enthält.

Die Generierung findet hier in einem eigenen Dialog statt, der ähnlich wie beim XEmacs nur die Ausgaben von Make sammelt und keine Eingaben auf Shell-Ebene erlaubt. Bei Fehlern kann zurück zum Code gesprungen werden. Als Debugger ist standardmäßig der gdb integriert.


CodeWarrior

CodeWarrior von Metrowerks kam als Erstes für den Apple Macintosh auf den Markt und war lange Zeit die wichtigste IDE auf dieser Plattform. Mittlerweile gibt es auch Portierungen für andere Betriebssysteme, seit einiger Zeit auch für Linux (siehe www.metrowerks.com/desktop/linux/). Das Programm nicht allerdings kostenlos, sondern muss käuflich erworben werden!

Die Bedienparadigmen des Mac sind noch an ein paar Stellen des CodeWarrior offensichtlich. So erhalten Sie unmittelbar nach dem Start kein vollständiges Fenster, sondern lediglich ein Fensterchen, das nur aus einer Menüleiste besteht. Über diese lassen sich dann alle weiteren Kommandos aufrufen.

Wenn Sie über FILE | NEW PROJECT ein neues Projekt öffnen, haben Sie neben einem völlig leeren Projekt auch die Möglichkeit, über eine Vorlage schon ein (meist sehr einfaches) Gerüst erzeugen zu lassen.

Vorbildlich sind die Projekteinstellungen (Abbildung [*]): Für jeden Dateityp lässt sich (prinzipiell) ein eigenes Übersetzungswerkzeug definieren. Leider steht in dieser Version nur der GCC zur Verfügung. Auch Compiler-Optionen und Pfade lassen sich damit sehr einfach setzen.

Figure: Die Projekteinstellungen beim CodeWarrior sind ebenso übersichtlich wie vielseitig.

\resizebox*{1\columnwidth}{!}{\includegraphics{/usr/homes/thomas/cpp/cpp_linux/Text/images/cw-settings.eps}}

Oftmals hat die IDE aber das Problem, dass ihre Schrift auf einem Bildschirm höherer Auflösung sehr klein wirkt. Neben den Einstellungen sind auch der Projekteditor und der Klassenbrowser davon betroffen.

An höheren Werkzeugen verfügt der CodeWarrior über einen Hierarchiebrowser, einen Klassenbrowser und einen Symbolbrowser. Die Abhängigkeiten der Header-Dateien werden über eine kleine Schaltfläche im Projekteditor sichtbar gemacht.

Die Übersetzung erfolgt in der Shell, aus der man die IDE (übrigens mittels cwide) gestartet hat. Die Ausgaben laufen dann allerdings wieder in ein eigenes ERROR & WARNINGS-Fenster. Selbst Sonderfunktionen des GCC wie separater Syntaxcheck oder alleiniges Preprocessing sind aus der IDE aufrufbar.

Der Editor erfüllt alle Anforderungen, die man beim Programmieren braucht, hat eine vernünftige Syntaxeinfärbung und erlaubt leichtes Navigieren. Unterstützt wird dieses besonders durch Lesezeichen, die man im Code anbringen kann. Auch der Sprung zwischen den Funktionen und Methoden wird durch ausklappbare Listen erleichtert. Eine Anbindung an die Versionsverwaltung gibt es ebenso. Wer darauf verzichten möchte, darf auch hier einen externen Editor verwenden.

Die Debugger-Anbindung glänzt durch eine ganze Reihe von Ausgabefenstern, etwa für Prozesse, Ausdrücke, globale Variablen oder Haltepunkte. Andererseits ist auch die Einbindung eines externen Debuggers wie des DDD ohne weiteres möglich.

Insgesamt unterscheidet sich der CodeWarrior in seinem Funktionsumfang nicht grundsätzlich vom Source Navigator oder von SNiFF+. Da er im Gegensatz zu den beiden anderen aber nicht kostenlos angeboten wird, ist er wohl eher für Entwickler geeignet, die damit schon einige Erfahrung haben und beim Plattformwechsel ihr Werkzeug weiterverwenden wollen.


Eclipse

Die neueste und viel beachtete integrierte Entwicklungsumgebung unter Linux ist Eclipse. Es handelt sich dabei um ein Produkt der ehemaligen Visual Age-Familie von IBM, das die Firma im November 2001 als Open Source freigegeben hat. Seitdem wird Eclipse von einer über 1200 Entwickler starken Community, zu der auch namhafte Firmen wie Merant, QSSL, Rational, Red Hat und TogetherSoft gehören, mit großem Nachdruck weiterentwickelt. Ausführliche Informationen und die neuesten Releases erhalten Sie von der Projekt-Website www.eclipse.org.

Die Idee von Eclipse

Ein Kerngedanke des Eclipse-Projektes besteht darin, dass heutige Entwicklungsprojekte kaum noch mit einer einzigen Programmiersprache auskommen, sondern meist aus einer Mischung von verschiedenen Programmierparadigmen und Technologien wie C++, Java, Python, HTML und XML bestehen. Für jede dieser Technologien muss der Entwickler jedoch meist ein eigenes Tool verwenden, das diese unterstützt (wenn man von dem Alleskönner Emacs einmal absieht, den selbst professionelle Entwickler nicht immer lieben). Jedes Werkzeug verfolgt aber eine eigene Philosophie und erfordert eine Einarbeitung, was zu einem beträchtlichen Aufwand führt.

Eclipse möchte daher nicht einfach ein weiteres Tool sein, sondern eine universelle Plattform, über die die verschiedenen Werkzeuge benutzt werden können. Es handelt sich bei Eclipse also mehr um eine generische IDE, in die durch einen Plug-in-Mechanismus viele andere Werkzeuge eingebunden werden können, darunter auch eine IDE zur C++-Programmierung. Als Benutzer sollten Sie kaum merken, wie die verschiedenen Tools ineinander greifen (siehe dazu auch []).

Als echtes Open-Source-Projekt (unter einer Apache-ähnlichen Lizenz) verfügt Eclipse über völlig offene Schnittstellen, die es jedem ermöglichen, eigene Beiträge für die Plattform zu schaffen. Und wie bei vielen anderen Open-Source-Projekten dauert es auch etwas, bis ein Reifegrad erreicht ist, der einen tatsächlichen Einsatz in der Praxis möglich macht. Für die C++-Entwicklung war dies nach meiner Erfahrung zum augenblicklichen Zeitpunkt (April 2002) noch nicht der Fall. Generell machte Eclipse unter Windows einen deutlich stabileren Eindruck als unter Linux. Da sich die Situation aufgrund der großen Beteiligung an diesem Projekt jedoch bald ändern kann, möchte ich Ihnen die Grundzüge des aktuellen Eclipse schon einmal vorstellen. Es lohnt sich sicherlich, ab und zu einen Blick auf dieses Projekt zu werfen.

Die Eclipse-Plattform unter der Haube

Die Eclipse-Plattform setzt sich aus folgenden Bestandteilen zusammen:

Die gesamte grafische Oberfläche von Eclipse ist mit Hilfe von SWT programmiert. Es handelt sich dabei um eine Bibliothek von grafischen Komponenten (den so genannten widgets, was für window gadgets, also Fensterelemente steht). Sie ist selbst in betriebssystemabhängiger Form entwickelt, das heißt, sie nutzt die Möglichkeiten des jeweiligen Fenstersystems (Windows, Motif etc.), bietet aber eine unabhängige Programmierschnittstelle (API) an. Entwickler können damit Benutzerschnittstellen schreiben, die genauso unter Linux wie unter Windows und anderen Betriebssystemen laufen. Anders als etwa das AWT-Toolkit von Java versucht SWT, eine große Vielfalt von Steuerelementen zur Verfügung zu stellen, wobei im Allgemeinen die Controls des jeweiligen Fenstersystems genutzt werden; ist ein solches jedoch nicht vorhanden, bietet SWT eine Emulation.

Um die Programmierung von GUIs unter Java noch weiter zu vereinfachen, bildet JFace noch eine Abstraktionsschicht über SWT. JFace enthält Komponenten für die Auswahl von Bildern und Zeichensätzen, Baukästen für Dialoge und Assistenten sowie Fortschrittanzeigen. Darüber hinaus stellt es Möglichkeiten für die Gestaltung interaktiver Betrachter (Viewer) zur Verfügung.

Eclipse als IDE

Die Installation von Eclipse ist sehr einfach. Sie müssen lediglich das heruntergeladene Archiv in ein Verzeichnis auspacken (zum Beispiel nach /opt/eclipse) und Ihre path-Variable darauf setzen. Die Unterstützung für C++ befindet sich in einem separaten Plug-in, das Sie ebenfalls herunterladen und auspacken müssen. Es kommt in das Unterverzeichnis plugins, also etwa

% unzip cdt-eclipse.zip -d /opt/eclipse/plugins

Eclipse geht davon aus, dass Sie in dem Verzeichnis arbeiten wollen, von dem Sie es aufrufen. Wechseln Sie also vor dem Start dorthin oder geben Sie das Arbeitsverzeichnis mit an, wenn Sie einen Link für diese Anwendung auf dem Desktop oder im KDE/GNOME-Menü anlegen. Bei meinen Tests mit Beta-Releases der Version 2.0 im Frühjahr 2002 erschien bei Aufruf des Programms nur das Projektlogo - danach passierte nichts mehr. Da half nur noch der direkte Start der Java-Applikation, entweder über

% java -classpath /opt/eclipse/startup.jar \

org.eclipse.core.launcher.Main -ws motif

oder gar als

% jdb -classpath /opt/eclipse/startup.jar \

org.eclipse.core.launcher.Main -ws motif

Nach dem Start fällt als Erstes die Aufteilung des Hauptfensters in verschiedene Teilbereiche auf. Es repräsentiert die verschiedenen Werkzeuge, die zum Startzeitpunkt geladen sind. Meist sichtbar ist der Navigator, eine Art Projektmanager, der die im Arbeitsverzeichnis vorhandenen Projekte und Unterprojekte sowie die zugehörigen Dateien anzeigt.

Figure: Die Eclipse-IDE setzt sich aus vielerlei Werkzeugen zusammen.

\resizebox*{1\columnwidth}{!}{\includegraphics{images/eclipse.eps}}

Wenn Sie ein neues Projekt anlegen möchten, verwenden Sie dazu den Projektassistenten, den Sie mit FILE | NEW | PROJECT erreichen. Wenn Sie das C++-Development-Toolkit installiert haben, finden Sie in der Auswahlliste auf der linken Seite auch C/C++, das Ihnen nach Anklicken rechts die Möglichkeit gibt, C/C++ Project auszuwählen. Im nächsten Dialog können Sie nun einen Namen für das Projekt festlegen und bestimmen, ob es sich in einem lokalen Verzeichnis oder auf einem anderen Rechner befinden soll. Mit FINISH schließen Sie das Anlegen des neuen Projektes ab.

Nun hat sich das Navigator-Werkzeug verändert. Es hat noch einen Reiter C/C++ PROJECTS am unteren Rand hinzubekommen; in diesem Modus erscheinen nur die C/C++-Projekte, alle anderen sind ausgeblendet.

Wenn Sie schon ein bestehendes klassisches C++-Projekt - mit Dateien und einem Makefile - haben, können Sie es mit FILE | IMPORT auch zu Ihrem gerade angelegten Eclipse-Projekt hinzufügen. Nach der Auswahl eines Verzeichnisses haben Sie sogar die Möglichkeit anzugeben, welche Dateien in diesem Verzeichnis übernommen werden sollen und welche nicht.

Wenn Sie nun noch bei diesem Projekt im Navigator PARSE | BEGIN PARSE aus dem Kontextmenü wählen, durchkämmt Eclipse Ihren Code nach allen Arten von Deklarationen und listet diese im Project Objects-Werkzeug auf. Hier können Sie nun eine Methode oder eine Klasse auswählen und durch einen Doppelklick deren Deklaration beziehungsweise Implementierung im Editor öffnen.

Ein Vorteil von Eclipse ist sicherlich, dass Sie nicht mühsam selbst Makefiles schreiben müssen, sondern dass diese Aufgabe von der IDE übernommen wird. Eclipse arbeitet hierbei mit autoconf, einem Werkzeug, das Ihnen die Projektkonfiguration und das Erzeugen von Makefiles noch weiter vereinfachen will. Zum Bauen eines Programms wird aber das übliche make verwendet.

Im Zentrum jeder IDE steht jedoch der Editor. Syntaxeinfärbung beherrscht der Eclipse-Editor für C++ recht gut. Interessant sind auch die Möglichkeiten zur automatischen Codeformatierung, die jedoch für Java schon weiter entwickelt sind als für C++. Auch sonst stellt der Editor mit Rechteckauswahl, Vergleichen, Aufzeichnung von Tastenanschlägen und Ähnlichem ein bemerkenswert breites Spektrum von Funktionsmerkmalen zur Verfügung. An Visual Studio orientiert sich etwa die Möglichkeit, die Anzeige des Codes gefiltert darzustellen (FILTER VIEW im Kontextmenü).

Interessant sind auch die so genannten Perspektiven. Diese kleinen Symbole am linken Rand stellen verschiedene Sichten auf die IDE dar, wobei die Werkzeuge jeweils in unterschiedlichen Größen und Anzeigeformen auftauchen. Auf diese Weise können Sie je nach dem Arbeitsschritt, an dem Sie gerade sind, die für Sie angenehmste Kombination an Werkzeugen definieren. Über die Punkte im Menü PERSPECTIVE können Sie die Perspektiven relativ frei konfigurieren.

Wie auch schon SNiFF+ ist Eclipse lediglich eine IDE, die auf den vorhandenen Programmen aufsetzt, und beispielsweise den GCC zum Kompilieren und den gdb fürs Debuggen verwendet. Sie starten das Übersetzen mittels WORKBENCH | REBUILD ALL und kontrollieren das Starten und die Fehlersuche (in Ihrem Programm, nicht in Eclipse ...) über das DEBUG-Menü.

Eclipse wird in Java entwickelt und dementsprechend ist die Unterstützung für Java auch die am weitesten fortgeschrittene. Daher gibt es dort schon eine interessante Funktion, die bei C++ noch nicht vorhanden ist: das Refactoring. Damit meint man das Umstrukturieren und Umgestalten von Code, wenn er nicht mehr den Erfordernissen entspricht oder zusätzliche Funktionalität erfüllen soll (siehe []). Mit den Refactoring-Funktionen in Eclipse können Sie - wie gesagt zunächst nur bei Java - Namen von Attributen, Methoden und Klassen verändern, Klassen in der Hierarchie verschieben und neue Klassen zwischen alte einfügen. Die notwendigen Änderungen werden dann automatisch im gesamten Projektcode nachgezogen. Auf diese Weise haben Sie immer einen konsistenten Code, auch wenn Sie Ihr Programm gründlich umorganisiert haben.

Fazit

Eclipse ist durch sein sehr offenes Plattformkonzept eine interessante IDE. Nicht zuletzt die große Unterstützung durch eine ganze Reihe von Firmen, angeführt von IBM, berechtigt zu großen Hoffnungen. Für die C++-Entwicklung ist Eclipse aber noch nicht reif. Hier fehlt es noch an Stabilität und sprachspezifischer Funktionalität. Wenn diese aber einmal vorhanden sind, kann sich Eclipse durchaus mit anderen Werkzeugen messen.

Zusammenfassung

In diesem Abschnitt haben Sie drei weitere grafische Entwicklungsumgebungen unter Linux kennen gelernt. Der Source Navigator von Red Hat bietet Ihnen die meisten der Funktionen, die Sie schon bei SNiFF+ gesehen hatten. Der CodeWarrior von Metrowerks bringt dagegen eine eigene Bedienphilosophie mit sich, was Ihnen den Umstieg auf Linux erleichtert, wenn Sie bereits auf einer anderen Plattform mit dieser IDE gearbeitet haben. Eclipse ist eine viel versprechende IDE, die als reines Open-Source-Projekt zwar von vielen namhaften Firmen unterstützt wird, aber erst noch eine gewisse Reife erlangen muss, um wirklich alltagstauglich zu sein - insbesondere im Hinblick auf die C++-Entwicklung.

Diese Auswahl ist bei weitem noch nicht vollständig. Ich habe vielmehr versucht, Ihnen die derzeit aus meiner Sicht wichtigsten Entwicklungsumgebungen vorzustellen, damit Sie selbst entscheiden können, welche Ihnen am besten gefällt und Ihre Anforderungen am ehesten erfüllt. Denn letztlich sollen alle Ihnen ja nur dabei helfen, Ihre eigenen Programme zu entwickeln - denn den Quelltext müssen Sie immer noch selbst schreiben.


next up previous contents index
Next: Bibliography Up: C++-Entwicklung mit Linux Previous: Werkzeuge für die Softwareentwicklung   Contents   Index
thomas@cpp-entwicklung.de