# Kapitel 10. Erweiterung der GUI

Wie wir gesehen haben, haben wir KScribble bereits die Fähigkeit gegeben, Bilder mit der Dokumentklasse zu öffnen und zu speichern, haben durch Überladen virtueller Methoden Interaktion ermöglicht, und wir haben die erste Funktionalität erreicht- wir können auch Bilder zeichnen. Aber als wir die `QPen` Instanz erzeugt haben, haben wir vordefinierte Werte für den Stift verwendet; die Farbe ist Schwarz und die Breite ist auf 3 Pixel eingestellt. Da Sie für gewöhnlich diese Werte ändern können wollen, müssen wir die Haupt-GUI um Funktionen, diese Werte zu setzen, erweitern, je nachdem welches Fenster gerade aktiv ist und welches Dokument damit verbunden ist. Dieses Kapitel wird Ihnen daher zeigen:

- Das Hinzufügen eines neuen Menüs zur Menüleiste

- Erweiterung der Werkzeugleiste um Icons, für die in der Menüleiste definierten Methoden

- Die Erstellung eines neuen Dialoges mit dem KDevelop Dialogeditor

- Verbinden der neuen Kommandos der Menü- und Werkzeugleiste mit Aufrufen der Dialoge

- Ermöglichen der Änderung der Stiftgröße in der Dokumentklasse

Desweiteren fügen wir eine Methode hinzu, den Inhalt des gesamten Dokuments über das Menü zu löschen.

# 10.1. Hinzufügen des "Stift" Menüs

Wie der Name dieses Abschnittes schon sagt, werden wir hier ein Menü zum Setzen der Stiftwerte des Dokuments hinzufügen. Menüs, die in die Menüleiste eingefügt werden, sind Instanzen von `QPopupMenu`, und Sie können einen Blick darauf werfen, wie die aktuelle Menüleiste aufgebaut ist, wenn Sie zur `KScribbleApp` Klasse, Methode `initMenubar()` wechseln. Sie werden sehen, daß die Menüleistenelemente in der Reihenfolge ihres Erscheinens auf der Menüleiste erzeugt wurden, aber das ist nicht notwendigerweise so. Es gibt zwei Dinge, die für das Aussehen der Menüleiste wichtig sind:

- In den Menüs, die Reihenfolge der Einträge

- In der Menüleiste, die Reihenfolge der Popupmenüs

Schließlich und endlich werden wir zuerst die Menüs erzeugen müssen, indem wir den Konstruktor aufrufen. Die Klassendeklaration enthält bereits die Zeiger auf die Popupmenüs, also werden wir zuerst das "Stift" Menü hier einfügen:

       1 kscribbleapp.h
       2
       3 class KScribbleApp
       4 {
       5 .
       6 .
       7   private:
       8     QPopupMenu* pPenMenu;
       9
      10 }

Jetzt werden wir das Menü selbst erzeugen. Ändern Sie die Implementation der Methode `KScribbleApp::initMenuBar()` und editieren Sie die, mit dem Pfeil markierten Zeilen:

       1 void KScribbleApp::initMenuBar()
       2 {
       3 ..
       4
       5 ->  ///////////////////////////////////////////////////////////////////
       6 ->  // menuBar entry pen-Menu
       7 ->  pPenMenu = new QPopupMenu();
       8 ->  pPenMenu->insertItem(i18n("&&;Color"), ID_PEN_COLOR);
       9 ->  pPenMenu->insertItem(i18n("&&;Brush"), ID_PEN_BRUSH);
      10
      11     menuBar()->insertItem(i18n("&&;Edit"), pEditMenu);
      12 ->  menuBar()->insertItem(i18n("&&;Pen"), pPenMenu);
      13     menuBar()->insertItem(i18n("&&;View"), pViewMenu);
      14
      15
      16 ->  connect(pPenMenu, SIGNAL(activated(int)), SLOT(commandCallback(int)));
      17 ->  connect(pPenMenu, SIGNAL(highlighted(int)), SLOT(statusCallback(int)));
      18 }

Sie sehen, daß wir zunächst das Menü mit `new QPopupMenu()` erzeugen. Dann verwenden wir die insertItem Methode, zum Hinzufügen der Menüeinträge Color und Brush. Die sichtbaren Kommandos werden mit der Methode `i18n()` eingefügt, womit sichergestellt ist, daß Sie Ihre Applikation internationalisieren können. Als generelle Regel kann gesagt werden, daß Sie alle später sichtbaren Texte mit der Methode `i18n()` deklarieren sollten. Nur-Qt Programme, die Qt > 2.0 verwenden, benutzen dazu die Methode `tr()`, da Qt eigene Verfahren hat, Anwendungen zu internationalisieren. Das zweite Argument ist ein Makro, die ID des Menüeintrages. Diese ID ist eine Nummer, die wir mit &#;define in der resource.h, in der Sie auch die anderen bisher definierten ID's finden, setzen müssen. Es gibt auch den Weg, Menüs direkt einzufügen, indem Sie einen Slot mit dem gewählten Eintrag verbinden, aber das Framework dieser Anwendung verwendet ID's, um festzustellen, welche Aktion ausgewählt und markiert wurde. Deshalb muß jeder Menüeintrag, unbhängig davon, in welchem Popupmenü er erscheint, eine einzigartige Nummer besitzen, und da wir uns Nummern schlecht merken können, ist die Verwendung eines &#;define für die ID eine gute Lösung. Das Popupmenü wird nun ebenfalls mit `insertItem()` der Menüleiste hinzugefügt, und zwar mit einem Zeiger auf das Menü als zweitem Argument. Beachten Sie, daß wir das Popupmenü nach dem Edit- und vor dem Viewmenü eingefügt haben, es wird also später zwischen diesen beiden Menüs erscheinen. Was auch wichtig bei der Erstellung von Menüs ist, ist, daß sie dem Benutzer auch über Shortcuts zur Verfügung gestellt werden sollten; normalerweise sehen Sie in Menüs einen unterstrichenen Buchstaben, der zusammen mit ALT die entsprechende Funktion aufruft. Als Programmierer, müssen Sie diesen Buchstaben durch ein vorangestelltes "&&;" setzen, das "Pen" Menü wird also später durch drücken von ALT+P erreichbar sein. Innerhalb des Menüs kann der Benutzer auch nur den Buchstaben eingeben, um den entsprechen Menüpunkt auszuführen, Sie sollten also für die anderen Menüpunkte ebenfalls Tastaturkürzel zur Verfügung stellen. Achten Sie darauf, den Code zum Einfügen von Einträgen in Gruppen zusammenzuschreiben, die Sie überblicken können, damit Sie keine Kürzel doppelt verwenden (Dies ist auch für Ihre Übersetzer wichtig: In anderen Sprachen kommt das gewählte Kürzel vielleicht nicht im Menütext vor, der Übersetzer muß also auch wieder ein Kürzel auswählen).

In den letzten beiden Zeilen verbinden wir die Stiftmenüs mit zwei Slots: einen für das Menüsignal "aktiviert, Aktion ausführen" und einen für die Markierung des Menüeintrages. Dies ermöglicht es, eine Hilfemeldung in der Stauszeile anzuzeigen. Sie können sich die Methoden ansehen, die mit dem Menü verbunden sind. Sie enthalten Anweisungen, in denen die gesendete ID geprüft und die folgende Aktion aufgerufen wird. Was noch zu tun bleibt, ist die &#;define Anweisungen in die resource.h einzutragen:

       1
       2 resource.h ///////////////////////////////////////////////////////////////////
       3 // Pen-menu entries
       4 #define ID_PEN_COLOR                14010
       5 #define ID_PEN_BRUSH                14020

Sie sehen, daß die Nummern für jeden Eintrag einzigartig sind. Sie müssen darauf achten, nicht zweimal dieselbe Nummer zu vergeben. Sollte es aber dennoch einmal versehentlich passieren, wird Sie der Compiler über die Redefinition informieren.

Das ist zum jetzigen Zeitpunkt alles, das Sie zum Hinzufügen eines neuen Menüs tun müssen. Die ausgeführten Aktionen sind: "Color" (Aufruf des Farbauswahldialogs) und "Brush" (Aufruf des Dialogs zum Setzen der Stiftbreite). Letzeren Dialog werden wir noch erstellen, aber zuerst werden wir im nächsten Kapitel auch die Werkzeugleiste um zwei Icons für diese Aktionen erweitern.