# Kapitel 6. Anwendungskonzepte

Dieses Kapitel stellt Ihnen die Ideen der bereits erwähnten Applikationsmodelle vor: des MDI (Multiple Document Interface) und des Document View Modells. Eine Basiseinführung in das Doc-View Modell und die Generierung eines Projektes mit KDevelop ist schon im KDevelop Programming Handbook enthalten, aber auf Basis des Single Document Interfaces (SDI). In jedem Falle sollten Sie mit den Grundlagen der KDE und Qt Klassen vertraut sein, die in The KDE Library Reference Guide erklärt sind. Die Basisklassen der darunterliegenden Bibliotheken und ihre Verwendung werden dort im Detail beschrieben, außerdem finden Sie zusätzlich eine Beschreibung des Qt Signal-Slot Verfahrens und der Ereignisverarbeitung.

Sie sollten bereits wissen:

- Daß jede KDE Applikation eine Instanz von `KApplication` (bei Qt eine Instanz von `QApplication`) benötigt

- Generell ein Main Fenster von `KTMainWindow` bei KDE (for Qt von `QMainWindow`) abgeleitet ist

- Daß Ereignisse (z.B. Tastendrücke oder Mausbewegungen) von darunterliegenden Window System an die Anwendung gesendet werden

- Daß `QWidget` als Basisklasse für alle Graphical User Interface (GUI) Komponenten spezialisierte Event Handler durch virtuelle Funktionen bereitstellt, die die entsprechenden Events durch Reimplementation von `QObject::event()` ausfiltern

- Daß das Qt Signal-Slot Verfahren bedeutet, daß eine Komponente Signale aussendet und ein Empfänger sich mit diesen Signalen verbinden kann, um bestimmte Aktionen auszuführen.

- Daß dieser Mechanismus es unnötig macht, Klassen für GUI Komponenten zu beerben, weil die Signale Sie über z.B. Mausereignisse informieren, wo es passend für ein Widget ist.

# 6.1. Das Document-View Modell

Das Document-View Modell ist eines der grundlegendsten Konzepte für GUI basiertes Anwendungsdesign. Daher ist ein gewisses Verständnis für das "Warum" nötig, um zu erkennen, daß es Sinn macht es zu benutzen, obwohl der Programmierer andere Möglichkeiten hat. Lassen Sie uns aber zuerst einen Blick auf das normale Design einer typischen KDE / Qt Applikation werfen:

Die Instanz Ihrer Anwendung stellt die erste Verbindung zu Ihrer Applikation zu Verfügung und ist der Startpunkt der Ereignisbehandlung eines Programms. Das Programm selber präsentiert sich dem Benutzer über eine graphische Benutzerschnittstelle, die meistens Hauptfenster genannt wird. Das Hauptfenster stellt dann dem Benutzer die erforderlichen Funktionen zur Verfügung, wie Tastenkürzel, eine Menüleiste, eine Werkzeugleiste und eine Statuszeile. Im Zentrum befindet sich ein sogenannter "Ansichtsbereich", was bedeutet, daß dieser Bereich die Instanz einer anderen Klasse ist, normalerweise "Ansicht" genannt. Diese Instanz wird erzeugt, wenn das Hauptfenster beim Programmstart konstruiert wird und muß mit Hilfe einer Methode des Hauptfensters zum Ansichtsbereich gemacht werden: `setView(your&_;view)` bei KDE Applikationen die `KTMainWindow` verwenden, `setCentralWidget(your&_;view)` bei Qt Applikationen die `QMainWindow` verwenden. Nun, offensichtlich ist die Ansicht der Bereich, der verantwortlich für die Interaktion mit dem Benutzer ist, wenn die Daten, die er repräsentiert manipuliert werden sollen. Zum Beispiel könnten Sie `QMultiLineEdit` als Ansicht verwenden, und Sie hätten einen Editor. Dann könnten Sie die gegebenen Slots der Ansicht zur Kommunikation mit der Menüleiste oder der Werkzeugleiste folgendermaßen verwenden:

Während Sie die Menüleiste erstellen, möchten Sie eine Methode für das Kommando "Cut" im "Edit" Menü bereitstellen:

       pEditMenu->insertItem(BarIcon("editcut"), i18n("Cu&&;t"),view, SLOT(cut()),KAccel::Cut, ID_EDIT_CUT);

Dies erzeugt einen Menüeintrag im "Edit" Menü, der, wenn aktiviert, direkt den Slot `cut()` der Instanz `view` aufruft, wobei wir davon ausgehen, daß Sie diese Instanz als `QMultiLineEdit` erzeugt und sie zum Ansichtsbereich gemacht haben. Der Slot des MultiLineEdit wird aufgerufen und schneidet als Reaktion den ausgewählten Text aus, die Funktionalität dazu wird bereits von der Klasse selbst zur Verfügung gestellt, es gibt also keine Notwendigkeit von `QMultiLineEdit` zu erben, um einen Ansichtsbereich zu erzeugen, der fähig zu solchen Aktionen ist. Diese Funktionen können sofort aufgerufen werden und machen das Erstellen von Anwendungen sehr einfach; Sie brauchen nur die Anwendungsinstanz und das Hauptfenster mit den Verbindungen zu Ihrem Ansichtsbereich, und das ist alles ! Das bedeutet, ein einfacher Editor kann geschrieben werden, indem man eine einzige Klasse erzeugt, die das Hauptfenster definiert und das Ein- und Auslesen von Daten implementiert- nur einige Basisslots, die Ihre Hauptansicht selbst implementieren muß.

Aber hier ist nun der Grund für dieses mysteriöse Document-View Modell: Sie müssen selbst Methoden zur Verfügung stellen, um die Dateien mit dem `QMultiLineEdit` Ansichtsbereich lesen und schreiben zu können, und zwar innerhalb des Hauptfensterinterfaces. Das ist offensichtlich der einfachste und logischste Weg. Nun, wenn wir die Dateien und ihren Inhalt als ein sogenanntes "Dokument" betrachten, das wir mit dem Attribut eines "Objektes" in der C++ Terminologie beschreiben, ist der nächste Schritt nur ein kleiner: Ich habe ein Dokument, eine Ansicht und ein Hauptfenster- warum trenne ich diese drei Objekte nicht voneinander? Wir könnten auf einfache Weise eine kleine Klasse erzeugen, die eine Datei in einen Textstream liest und dann die Ansicht aufrufen, um diesen Text für den Benutzer sichtbar zu machen. Dasselbe gilt auch wieder für das Speichern der Datei- Die Dokumentklasse sollte dann eine Methode anbieten, den Text aus der Ansicht zu lesen und als Datei zu speichern. Im Beispiel wären diese beiden Methoden die einzigen Aktionen die von der Dokumentklasse ausgeführt werden müssten, weil die Edit-Ansicht bereits alle Methoden über Slots bereitstellt, die für einen Editor benötigt werden, und Sie können den Inhalt der Ansicht direkt über diese Slots manipulieren.

Nun, die Hauptidee hinter dieser Aufteilung in drei Objekte (Dokument, Ansicht, Hauptfenster), anstatt der minimal zwei (Ansicht und Hauptfenster), ist folgende Frage: Was, wenn ich dem Benutzer die Möglichkeit geben will mit zwei oder sogar mehr Ansichten zu arbeiten? Solche Dinge kann man sogar mit nur einem Hauptfenster durch Trenner erreichen, wobei zwei Instanzen einer Datei angezeigt werden. Die Lösung kann dann nur sein, daß, wenn der Benutzer den Dateiinhalt in einem Fenster verändert, die andere Ansicht darüber informiert wird und ihren Inhalt aktualisieren muß. Sonst würde folgendes passieren: Wenn der Benutzer in einer Ansicht am Anfang etwas ausschneidet, dann am Ende der anderen Ansicht einfügt und dann die erste Ansicht schließt, würde die Datei mit beiden Teilen gespeichert, weil die zweite Ansicht nichts von dem Ausschneiden weiß. Das bedeutet, daß die beiden Asichten synchronisiert werden müssen, und das kann erreicht werden, indem alle Ansichten ständig über alle Benutzeraktionen informiert werden. Welche Ansicht der User tatsächlich verwendet sollte egal sein. Das bedeutet, daß schließlich eine Dokumentklasse benötigt wird, die alleine den wahren Inhalt des Dokumentes enthält und den Ansichten die Möglichkeit bietet, diesen zu verändern.

Ich hoffe, dies konnte einen Einblick in dieses Modell geben, obwohl es in den meisten Fällen so scheint, als ob der Programmierer ohne es leben könne- genauso könnte er auch ein Widget selber schreiben, das die Benutzeraktionen behandelt, anstatt einfach eine vorgebene Klasse als Ansichtsbereich zu verwenden, solange Sie nur ein Dokument in einem Ansichtsbereich präsentieren, kann die Ansicht auch für die Daten verantwortlich sein und nur Methoden zum Lesen oder Speichern einer Datei zur Verfügung stellen. Das nächste beschriebene Modell wird sich in diesem Punkt unterscheiden- dort werden Sie die tatsächliche Notwendigkeit und die Funktionalität, die die Dokumentklasse bereitstellt, erkennen.