KDE-Programmierung
von Burkhard Lehner (b_lehner@informatik.uni-kl.de)

KDE (K Desktop Environment) ist ein sich sehr rasant entwickelndes Projekt, das den Versuch unternimmt, eine einheitliche Oberfläche mit vielen Applikationen auf möglichst vielen Unix-Systemen zur Verfügung zu stellen. Der Vortrag gibt einen Einblick in die Programmierung von Applikationen mit den von KDE bereitgestellten Bibliotheken und erläutert die Grundlagen der grafischen Bibliothek Qt, die als Grundlage des KDE-Projektes dient.

Inhalt

Was ist KDE? Was ist Qt?
Hello, World!
Überblick Qt
    Bereitgestellte Klassen
    Signal/Slot-Konzept
Überblick KDE
    Bereitgestellte Klassen
    Compilieren mit dem configure-Skript
    Vielsprachige Programme mit KLocale und i18n
Kontaktadressen
    WWW-Seiten
    FTP-Server
    Mailing-Listen

Was ist KDE? Was ist Qt?

KDE (K Desktop Environment) ist ein Projekt, das es sich als Ziel gesetzt hat, eine einheitliche grafische Benutzeroberfläche für alle Applikationen zur Verfügung zu stellen, die auf möglichst vielen Unix-Plattformen läuft. Es soll dadurch eine benutzerfreundliche, intuitive Bedienbarkeit erreicht werden. Für KDE-Programme sind eine Reihe von Anforderungen aufgestellt worden, die erfüllt sein sollten. Sie sollten beispielsweise vollständig an die eingestellte Landessprache anpassbar sein, sollten über einen grafischen Benutzerdialog konfigurierbar sein, sollten einer bestimmte Menüstruktur folgen und möglichst festgelegte Tastenkombinationen benutzen.

Die wichtigesten Programme des KDE-Projektes sind:

...und viele andere mehr. Fast täglich erscheinen neue Applikationen für das KDE-Projekt im Internet. Nahezu alle bisher im KDE-Projekt veröffentlichten Applikationen sind unter der General Public Licence (GPL bzw. LGPL) veröffentlicht, daher sind Programme und Quellcodes frei verfügbar.

Die Grundlage für die grafische Benutzeroberfläche für KDE-Programme ist die Bibliothek Qt der Firma Troll-Tech in Norwegen. Qt stellt eine sehr komfortable und mächtige Schnittstelle zur XLib dar und enthält eine große Anzahl an vordefinierten Widgets (Elemente für ein grafisches User-Interface) wie z.B. Buttons, Input-Felder, Menüs, Combo-Boxen, Schieberegler, Tabellen und vieles andere mehr. Außerdem enthält es eine Reihe von sehr nützlichen C++-Klassen und Templates, die einem Programmierer das Leben erleichtern, z.B. Strings, dynamische Arrays, Listen, Hash-Tabellen.

Qt ist ein kommerzielles Produkt, Lizenzen verkauft die Firma Troll Tech auf Developer-Basis: Für 1200 USD kann ein Programmierer eine Lizenz für Unix-Systeme erhalten, und darf dann alle von ihm mit Qt entwickelten Programme verkaufen, ohne dass weiter Lizenzgebühren fällig werden. Er darf dabei sowohl statisch als auch dynamisch gelinkte Programme vertreiben. Speziell für den Free-Software-Bereich bietet Troll Tech aber auch die Qt Free Edition an: Man kann das vollwertige Qt kostenlos als Quelltext(!) oder als Binaries für verschiedenen Unix-Plattformen bei Troll Tech downloaden und benutzen.

Seit der Version Qt 2.0 unterliegt diese Qt Free Edition den Lizenzbestimmungen der QPL (Qt Public Licence). Im Gegensatz zu früher darf der Qt-Sourcecode nun sogar verändert und weitergegeben werden, mit bestimmten Einschränkungen. So will die Firma Troll Tech erreichen, dass schneller auf Bugs und Verbesserungen eingegangen werden kann. Die Qt Free Edition unterliegt aber weiterhin der Einschränkung, dass mit ihr entwickelte Programme nur als freie Software (also z.B. unter der GPL) verbreitet werden dürfen. Für eine kommerzielle Nutzung ist in jedem Fall eine Entwicklerlizenz nötig. Eine Anmeldung oder Registrierung bei Troll Tech ist für die Benutzung der Qt Free Edition nicht nötig.

Qt ist also keine freie Software, darf aber zur Entwicklung von freier Software kostenlos genutzt werden. Die genauen Lizenzbedingungen, die sehr ausführliche und übersichtliche Dokumentation sowie ein Tutorial für Einsteiger sind unter http://www.troll.no/ erhältlich. Unter diesem URL ist auch ein Download der Qt Free Edition möglich.

Als KDE-Programmierer sollte man sich also in folgende Dinge einarbeiten:

C++:
KDE und Qt sind in C++ geschrieben und machen intensiven Gebrauch von der Klassenstruktur. Als KDE-Programmierer sollte man also neben C-Kenntnissen auch die Objektorientierung von C++, insbesondere Klassendefinitionen und Vererbung, kennen. Kenntnisse über Templates, virtuelle Methoden und Operatorüberladungen sind auch recht nützlich.
Qt-Klassen:
Man sollte sich einen guten Überblick über die von Qt zur Verfügung gestellten Klassen und Templates verschaffen, um alle Möglichkeiten von Qt nutzen zu können und nicht das Rad neu erfinden zu müssen.
KDE-Klassen:
KDE stellt einige spezielle Klassen zur Verfügung. Neben weiteren Widgets gibt es Klassen zum komfortablen Einlesen und Ändern von KDE-Konfigurationsdateien, sowie den Zugriff auf den kwm und den kfm.

Kenntnisse über den Aufbau und die Funktionsweise von X-Servern und der XLib sind nicht nötig, können aber vielleicht manchmal hilfreich sein. Kenntnisse über Makefiles sind oft nützlich.

Für Ihre eigenen Versuche benötigen Sie das Paket Qt (zur Zeit in der Version 1.43, oder als Version 2.0 im Beta-Stadium) in der Entwicklerversion(!), sowie mindestens die KDE-Pakete kdebase, kdelibs, kdesupport und kdesdk (zur Zeit in der Version KDE 1.1). Beachten Sie, dass KDE 1.1 voraussichtlich nicht mit Qt 2.0 lauffähig sein wird.

Hello, World!

Folgendes Programm stellt wahrscheinlich gleichzeitig eines der kürzesten KDE-Programme und eines der komfortabelsten "Hello, World"-Programme dar.

 1. // khelloworld.cpp
 2.
 3. // Hello World for KDE
 4. // by Burkhard Lehner <b_lehner@informatik.uni-kl.de>
 5.
 6. #include <kapp.h>
 7. #include <kmenubar.h>
 8. #include <ktmainwindow.h>
 9. #include <qlabel.h>
10. #include <qkeycode.h>
11.
12. int main (int argc, char **argv) {
13.
14.   const char *aboutText = "KDE Hello World\nby Burkhard Lehner";
15.
16.   KApplication a (argc, argv);
17.   KTMainWindow top;
18.
19.   QPopupMenu *filePopup = new QPopupMenu ();
20.   filePopup->insertItem (i18n ("&Quit"), &a, SLOT (quit ()), CTRL + Key_Q);
21.
22.   KMenuBar *menu = top->menuBar();
23.   menu->insertItem (i18n ("&File"), filePopup);
24.   menu->insertSeparator ();
25.   menu->insertItem (i18n ("&Help"), a.getHelpMenu (TRUE, aboutText));
26.
27.   QLabel *text = new QLabel (i18n ("Hello, World"), &top);
28.   text->setAlignment (AlignCenter);
29.   text->setFont (QFont ("charter", 64, QFont::Bold, TRUE));
30.   text->setMinimumSize (text->sizeHint ());
31.   top.setView (text);
32.
33.   top.show ();
34.   return a.exec ();
35. }

Screenshot vom Hello-World-Programm

Kurze Erläuterung zum Quellcode:

Zeilen 6 - 10:

Alle benutzen Klassen von KDE und Qt müssen durch Includen der entsprechenden Header-Dateien definiert werden. Die Header-Dateien der KDE-Klassen beginnen in der Regel mit einem 'k', die der Qt-Klassen mit einem 'q'. Die Header-Dateien sind in diesem Fall zuständig für die Definition der Klassen KApplication, KMenuBar, KTMainWindow und QLabel, die fünfte Header-Datei definiert die Konstanten CTRL und Key_Q für Zeile 20.

Zeilen 16, 17:

Ein KDE-Programm besitzt immer genau eine Instanz der Klasse KApplication und meist eine oder mehrere Instanzen der Klasse KTMainWindow. KApplication übernimmt die Initialisierung aller KDE-internen Daten (Einlesen der applikationsspezifischen Konfigurationsdatei, Erstellen der Übersetzungstabelle für länderspezifische Menüs, Analysieren der KDE und X11 betreffenden Kommandozeilenparameter). Bevor diese internen Daten nicht angelegt sind, sollte auf kein KDE- oder Qt-Objekt zugegriffen werden. Vorsicht daher mit statischen Objekten: deren Konstruktoren werden vor der main-Funktion ausgeführt! KTMainWindow stellt das Applikationsfenster dar, in das dann Menüleisten, Statusleisten und weitere Widgets eingefügt werden können.

Zeile 19, 20:

Hier wird ein neues Popup-Menü erzeugt, das erscheinen soll, wenn im Hauptmenü auf File geklickt wird. Dieses Popup-Menü enthält nur einen Eintrag Quit. Dieser Eintrag wird mit dem Slot quit () des Objektes a (also des KApplication) verbunden. Eine Auswahl dieses Menüpunktes bewirkt also ein Beenden des Programms. Für diesen Menüpunkt gibt es noch den globalen Shortcut Strg-Q. Die Eingabe von Strg-Q bewirkt also ebenfalls die sofortige Beendigung des Programms.

Zeile 22 - 25:

Es wird die Menüleiste erzeugt, die zwei Einträge File und Help enthält. Unter File wird das Popup-Menü aus den Zeilen 16 und 17 aufgerufen, unter Help das Standard-Helpmenü. Dieses enthält drei Punkte:

Contents:
Aufruf dieses Menüpunktes führt zum Aufruf des Programms kdehelp, das die HTML-Hilfedatei für diese Applikation anzeigt.
About Applicationname:
Zeigt in einem kleinen Fenster den About-Text an, der in Zeile 14 definiert wurde
About KDE:
Zeigt in einem Fenster allgemeine Informationen zu KDE.
Zeile 27 - 31:

Ein Label-Widget wird erzeugt, das zur Anzeige von Text dient. Dieses Label enthält den Schriftzug "Hello, World" (Zeile 27), stellt ihn zentriert dar (Zeile 28) mit dem Zeichensatz "Carter" in Größe 64 Punkt, fett und kursiv (Zeile 29), und ist immer mindestens so groß, dass der ganze Text dargestellt werden kann (Zeile 30). Dieses Widget wird als Hauptfenster im KTMainWindow eingetragen (Zeile 31).

Zeile 33:

Bisher wurde von diesen Widgets auf dem Bildschirm noch nichts angezeigt. Diese Zeile stellt jetzt das KTMainWindow sowie seine Child-Widgets (die Menüleiste und das Label-Widget) auf dem Bildschirm dar.

Zeile 34:

Die Event-Loop der Applikation wird gestartet. Ab diesem Zeitpunkt werden Mausbewegungen, Tastatureingaben und so weiter verarbeitet. Die Event-Loop wird erst verlassen, wenn das Programm über den Slot quit () der KApplication beendet wird.

Die Funktion i18n (char *):

Diese Funktion (genaugenommen ein Makro als abkürzende Schreibweise von KApplication::getKApplication()->getLocale()->translate(char *)) übersetzt den übergebenen String in einen String der gleichen Bedeutung in der für KDE eingestellen Sprache. Hat man in KDE beispielsweise als Sprache "deutsch" ausgewählt, so werden die Menüeinträge Datei und Hilfe heißen, und der angezeigte Text "Hallo, Welt". Woher die korrekten Übersetzungen kommen - schließlich enthält KDE keinen automatischen Übersetzer mit künstlicher Intelligenz - wird im Abschnitt "Vielsprachige Programme mit KLocale und i18n" besprochen. Es empfiehlt sich, alle Texte, die angezeigt werden sollen, mit dieser Funktion zu übersetzen. i18n ist übrigens die Abkürzung für "Internationalisation", die 18 steht dabei für die 18 Buchstaben, die ausgelassen worden sind.

Überblick Qt

Bereitgestellte Klassen

Hier eine kleine Auswahl der wichtigsten Klassen und Templates:

Allgemeine Klassen/Templates:

Klassen für Plattformunabhängigkeit:

Klassen für X-Strukturen:

Klassen für elementare Zeichenroutinen:

Klassen für GUI-Elemente:

Weitere Klassen:

Eine sehr ausführliche Referenz über alle Qt-Klassen finden Sie auf der Homepage der Firma Troll-Tech (http://www.troll.no/) sowie in der Dokumentation des Qt-Pakets (Developers Version).

Signal/Slot-Konzept

Callback-Routinen sind Funktionen oder Methoden, die ausgeführt werden sollen, sobald ein Widget einer Interaktion des Benutzers unterliegt, z.B. wenn ein Button gedrückt wird, ein Menüpunkt ausgewählt oder ein Scrollbar verschoben wird.

Callback-Routinen in Qt werden durch das sehr mächtige Signal/Slot-Konzept realisiert. Dazu sind in den Klassendefinitionen der Qt-Klassen zusätzliche Methoden als signal oder slot deklariert. Diese Methoden können beliebige Parameteranzahlen und Typen haben, der Rückgabewert muss aber in jedem Fall void sein. Verwechseln Sie nicht Signal-Methoden von Qt mit Signalen des Unix-Kernels, wie z.B. SIGTERM oder SIGKILL. Diese beiden Dinge haben nichts miteinander zu tun. Damit eine Klasse Signal- und Slot-Methoden benutzen kann, muss sie von der Klasse QObject abgeleitet sein. (Das sind z.B. alle GUI-Widgets, da sie von QWidget abgeleitet sind, welches seinerseits von QObject abgeleitet ist.)

Die Slot-Methoden sind Methoden, die eine Aktion als Folge einer Interaktion ausführen sollen. Sie müssen vom Programmierer mit Code gefüllt werden. Sie können weiterhin als private, protected oder public deklariert werden, ganz analog zu anderen Methoden, und können auch wie ganz normale Methoden aufgerufen werden.

Signal-Methoden werden vom Programmierer nur deklariert, jedoch nicht mit Code gefüllt. Der Code für die Methode wird vom Meta-Object-Compiler (moc) generiert und nachher zum Programm hinzugelinkt. Signal-Methoden werden innerhalb der Klasse aufgerufen, um anzuzeigen, dass eine Interaktion erfolgt ist, die eventuell eine Reaktion hervorrufen soll. Signal-Methoden führen keine Aktionen aus, sondern rufen nur Slot-Methoden auf, mit denen sie verbunden sind.

Um ein Signal mit einem Slot zu verbinden, benutzt man die Methode connect. Die einfachste Form der connect-Methode hat folgende Gestalt:

bool QObject::connect (const QObject * sender, const char * signal,
                       const QObject * receiver, const char * member)

Die Parameter sind dabei:

sender:
Objekt, dessen Signal-Methode verbunden werden soll
signal:
Name der Signal-Methode
receiver:
Objekt, dessen Slot-Methode beim Signal aufgerufen werden soll
member:
Name der Slot-Methode

Die Signal- und die Slot-Methode müssen in Parameteranzahl und -typen zueinander passen. Der Slot kann weniger Parameter haben als das Signal, die Typen müssen aber mit den ersten Parametern der Signal-Methode übereinstimmen.

Ein einfaches Beispiel soll zunächst erläutern, wie Signals und Slots verbunden werden:

    QScrollBar *scroll = new QScrollBar;
    QLabel     *label  = new QLabel;
    QObject::connect(scroll, SIGNAL(valueChanged(int)),
                     label,  SLOT(setNum(int)));

Die Klasse QScrollBar enthält eine Signal-Methode void valueChanged (int), die aufgerufen wird, sobald die Position des Scrollbars sich geändert hat. Die Klasse QLabel besitzt eine Slot-Methode void setNum (int), mit der man den Labeltext auf eine Zahl setzen kann.

Durch den Aufruf der Methode connect werden diese nun verbunden. Die Makros SIGNAL und SLOT übernehmen dabei die Umsetzung der Methodennamen in korrekte Zeichenstrings und müssen in der Methode connect immer benutzt werden. Nachdem Signal und Slot miteinander verbunden sind, führt jede Veränderung der Scrollbarposition durch den Benutzer zu einem Aufruf des Signals valueChanged, das alle damit verbundenen Slots aufruft, in diesem Fall also setNum, wodurch sich der Wert im Label ändert.

Ein Signal kann mit einer beliebigen Anzahl von Slots verbunden sein. Insbesondere kann sein Signal auch unverbunden bleiben. Verbindungen können mit der Methode disconnect wieder gelöst werden. Qt übernimmt das Lösen von Verbindungen automatisch im Destruktor von QObject, so dass ein Programmabsturz aufgrund eines Aufrufs einer nicht mehr vorhandenen Slot-Methode ausgeschlossen ist.

Hier nun ein Beispiel einer selbstdefinierten Klasse, die einen Slot definiert:

class myObject : QObject {

    Q_OBJECT            // Dieses Makro definiert Signals und Slots

public:
   myObject (QObject * parent=0, const char * name=0);
   ~myObject ();

public slots:
    void printMessage () {printf ("Knopf gedrückt!\n");}
}

Ist diese Klassendeklaration z.B. in der Datei myObject.h enthalten, so ist anschließend der Meta Object Compiler für dieses Header-File aufzurufen:

% moc myObject.h -o m_myObject.cpp

Dieser Aufruf erzeugt eine Datei m_myObject.cpp, die anschließend noch compiliert und zur ausführbaren Datei hinzugelinkt werden muss. (Alternativ kann man auch in der Datei, in der die Methoden der Klasse definiert sind, die von moc erzeugte Datei durch eine #include-Anweisung einfügen.)

Eine Verbindung sieht dann z.B. so aus:

QPushButton *button;
myObject *obj;
QObject::connect (button, SIGNAL (clicked ()),
                  obj,    SLOT (printMessage ()));

Anschließend wird bei jedem Druck auf die Taste der Text "Knopf gedrückt" ausgegeben.

Überblick KDE

Bereitgestellte Klassen

Neben den Klassen, die Qt dem Programmierer zur Verfügung stellt, enthält auch das KDE-Paket eine Reihe von Klassen, von denen hier einige stichwortartig vorgestellt werden sollen:

Nicht-grafische Klassen (KDE-core):

Grafische Klassen/Widgets (KDE-UI):

Weitere Widgets (nicht im KDE-Paket enthalten):

Compilieren mit dem configure-Skript

Jeder, der schon einmal eine KDE-Applikation compiliert hat, kennt den Dreisatz:

  % ./configure
  % make
  % make install

Der Aufruf des Shell-Skripts configure bestimmt die compilerrelevanten Daten des Systems, wie z.B. den Compiler, die KDE- und Qt-Pfade. Anschließend werden mit diesen Daten aus den Dateien Makefile.in die Dateien Makefile in allen Unterverzeichnissen der Applikation erstellt. Der Aufruf von make compiliert nun alle Source-Dateien und linkt sie zur einer ausführbaren Datei zusammen. make install kopiert schließlich alle Dateien an die richtige Stelle in der Verzeichnisstruktur.

Will man als Programmierer ebenfalls diese Methode übernehmen (was sehr anzuraten ist!), so lädt man sich am besten das Paket kdesdk (KDE Software Development Kit) vom KDE-FTP-Server und benutzt die darin enthaltenen Programme kapptemplate (textbasiert) oder kappgen (mit grafischer Oberfläche). Diese beiden erzeugen den Rahmen eines KDE-Programms, in die nur noch der eigene Code eingefügt werden muss. Weiterhin ist es empfehlenswert, sich automake und autoconf von GNU zu installieren. Eventuell muss man noch die Dateien Makefile.am in allen Unterverzeichnissen sowie die Datei configure.in im Hauptverzeichnis anpassen.

./Makefile.am:
Hier sind nur alle Unterverzeichnisse einzutragen. Solange Sie noch kein i18n benutzen (siehe "Vielsprachige Programme mit KLocale und i18n"), lassen Sie einfach das Unterverzeichnis po weg.
./yourapplikation/Makefile.am:
Ändern Sie APPSDIR auf das entsprechende Unterverzeichnis, um die Kategorie Ihrer Applikation festzulegen. Zur Zeit sind folgende Kategorien vorgesehen: Applications, Games, Graphics, Internet, Multimedia, System und Utilities. Solange Sie noch keine Hilfedateien vorbereitet haben, löschen Sie doc von SUBDIRS. Im unteren Teil tragen Sie die Namen der Sourcedateien ein, wie angegeben.
./configure.in:
In AM_INIT_AUTOMAKE tragen Sie den Namen und die Versionsnummer Ihrer Applikation ein. In AC_OUTPUT tragen Sie alle Makefiles ein, die erzeugt werden sollen, das sind in diesem Fall alle Makefiles, zu denen Sie das Makefile.am geändert haben, also mindestens Makefile und yourapplication/Makefile.

Anschließend können Sie make -f Makefile.dist aufrufen. Dadurch wird das Skript configure aus der Datei configure.in erzeugt.

Nun sollten Sie noch die Datei yourapplication.kdelnk anpassen.

Ihre Applikation benötigt eine Reihe von Icons, zwei Icons, die das Programm repräsentieren, und in den meisten Fällen eine Reihe von Icons für die Werkzeugleiste. Viele vordefinierte Icons sind im KDE-Verzeichnis bereits enthalten. Wenn Sie weitere Icons benötigen, so achten Sie darauf, dass Sie nur Farben der KDE-Palette benutzen. Sie können zum Beispiel das Programm kiconedit benutzen. Oder Sie wenden sich an das KDE-Icon-Team, das Icons für Sie erstellt. Schreiben Sie dazu eine eMail an Mark Donohoe unter donohoe@kde.org, und beschreiben Sie ihm Ihre Applikation und was Sie sich auf dem Icon vorstellen.

Danach können Sie mit ./configure, make und make install testen, ob das Compilieren und Installieren funktioniert. Eventuell brauchen Sie für das make install Superuser-Rechte.

Wenn Ihre Applikation soweit lauffähig ist, und Sie sie der Welt präsentieren möchten, so erzeugen Sie aus dem Sourcecode ein Paket im .tar.gz-Format. Führen Sie dazu vorher ein "make maintainer-clean" durch, um alle unnötigen Dateien zu löschen. Achten Sie auch darauf, dass im Paket weder die Datei config.cache noch die .deps-Verzeichnisse vorhanden sind. Sie sollten auf jeden Fall selbst in einem leeren Verzeichnis testen, ob Ihr Paket vollständig und compilierbar ist.

Vielsprachige Programme mit KLocale und i18n

KDE bietet eine komfortable Methode für Programmierer, die Programme in vielen verschiedenen Sprachen verfügbar zu machen. Die zentrale Rolle übernimmt dabei das Makro i18n, das bereits im "Hello, World"-Programm am Anfang des Artikels verwendet wurde. Wenn sie das configure-Skript von oben benutzen, wird Ihnen nochmals viel Verwaltungsarbeit abgenommen.

Gehen Sie folgendermaßen vor, um Ihr Programm zu internationalisieren:

  1. Umgeben Sie alle Zeichenketten, die in Ihrem Programm benutzt werden und die übersetzt werden sollen, mit dem Makro i18n (). Das kann dann z.B. so aussehen:

    vorher: printf ("Result of calculation: %d\n", res);
    nachher: printf (i18n ("Result of calculation:%d\n"), res);

    Die Namen von Einträgen und Gruppen in Konfigurationsdateien sollten nicht übersetzt werden, da es sonst Probleme beim Einlesen der Konfigurationsdateien gibt, falls die Landessprache gewechselt wird.

  2. Rufen Sie im Verzeichnis Ihrer Applikation make messages auf. Dadurch werden alle Zeichenketten, die übersetzt werden sollen, in die Datei messages.po geschrieben. Achtung: In der aktuellen Version von kexample (KDE Beta-4) wird noch ein älteres Makro translate statt i18n herausgefiltert. Ändern Sie bitte in der Datei Makefile.am im Applikationsverzeichnis folgende Zeile:

            $(XGETTEXT) -C -ktranslate $(khexdit_SOURCES)

    um in:

            $(XGETTEXT) -C -ki18n $(khexdit_SOURCES)

    Am Zeilenanfang muss ein Tabulator stehen!

  3. Kopieren Sie die Datei messages.po in das Verzeichnis po und benennen Sie es um in kapplication.pot, wobei kapplication wieder der Name ihrer Applikation ist.

  4. Falls Sie die Übersetzungen zum ersten Mal vornehmen, so kopieren Sie die Datei außerdem noch in das gleiche Verzeichnis mit den Namen sprache.po, wobei sprache das Länderkürzel der unterstützen Sprache darstellt. Wollen Sie beispielsweise Übersetzungen ins Deutsche und Norwegische anbieten, so kopieren Sie die Datei noch mit den Namen de.po und no.po. Falls Sie bereits einmal Übersetzungen gemacht haben und nun lediglich die Übersetzungstabelle aktualisieren wollen (da Sie beispielsweise neue Buttons oder Menüpunkte in Ihr Programm eingefügt haben), so führen Sie statt dessen im Verzeichnis po ein make merge aus. Dadurch werden neue zu übersetzende Texte in die Dateien eingefügt.

  5. Übersetzen Sie nun die Texte in den .po-Dateien. Die Texte stehen dabei in Paaren von Text und Übersetzung. Im "Hello, World"-Programm vom Anfang des Artikels sieht die messages.po-Datei zum Beispiel so aus:

            # SOME DESCRIPTIVE TITLE.
            # Copyright (C) YEAR Free Software Foundation, Inc.
            # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
            #
            #, fuzzy
            msgid ""
            msgstr ""
            "Project-Id-Version: PACKAGE VERSION\n"
            "POT-Creation-Date: 1998-05-18 21:49+0200\n"
            "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
            "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
            "Language-Team: LANGUAGE <LL@li.org>\n"
            "MIME-Version: 1.0\n"
            "Content-Type: text/plain; charset=CHARSET\n"
            "Content-Transfer-Encoding: ENCODING\n"
            
            #: khelloworld.cpp:18
            msgid "&Quit"
            msgstr ""
            
            #: khelloworld.cpp:21
            msgid "&File"
            msgstr ""
            
            #: khelloworld.cpp:23
            msgid "&Help"
            msgstr ""
            
            #: khelloworld.cpp:27
            msgid "Hello, World"
            msgstr ""

    Tragen Sie zunächst im oberen Teil die Informationen zum Programm ein. Anschließend schreiben Sie zwischen die Anführungsstriche hinter einem msgstr-Eintrag die Übersetzung des vorangegangenen msgid-Eintrags. Achten Sie dabei darauf, dass Sie das Format möglichst genau beibehalten. Im Beispiel von oben sähe eine Übersetzung dann z.B. so aus:

            msgid "Result of calculation: %d\n"
            msgstr "Ergebnis der Berechnung: %d\n"

    Einträge mit der Ergänzung #, fuzzy (außer dem Header-Eintrag) sind neu hinzugekommene Texte. Es wurde dabei versucht, die Übersetzung aus einem älteren Übersetzungstext zu erraten, was jedoch oftmals nicht ganz richtig ist. Wenn Sie auf einen solchen Eintrag stoßen, so korrigieren Sie evtl. den Eintrag in msgstr und löschen Sie die Zeile #, fuzzy. (Aber nicht im Header der .po-Datei!)

  6. Nachdem Sie alle .po-Dateien entsprechend bearbeitet haben, sollte Ihr Programm alle angeboteten Landessprachen unterstützen. Nachdem Sie ein make und ein make install gemacht haben, können Sie es aufrufen und testen, ob alle Texte korrekt übersetzt wurden.

Da nicht jeder Programmierer zwanzig oder mehr Sprachen sprechen kann, gibt es im KDE-Projekt ein Übersetzungsteam. Für Informationen hierzu und bei weiteren Fragen zum Thema Internationalisation (i18n), lesen Sie eine ausführlichere Anleitung unter http://www.kde.org/i18n.html, oder wenden Sie sich an die kde-i18n-Mailing-Liste (kde-i18n@kde.org).

Auch Qt enthält inzwischen eine Methode, um Textstrings der eingestellten Landessprache anzupassen. Diese Methode ist QObject::tr() und ordnet einem QString-Objekt ein anderes QString-Objekt zu. Dieses Verfahren hat den Vorteil, dass auch Unicode verarbeitet werden kann. Allerdings bietet das configure-Skript dafür noch keine Unterstützung an. Welche der beiden Varianten sich durchsetzen wird, oder ob beide verschmelzen werden, wird die Zukunft zeigen.

Kontaktadressen

WWW-Seiten

KDE allgemein: http://www.kde.org/
KDE Developers Center: http://www.ph.unimelb.edu.au/~ssk/kde/devel/
KDE i18n: http://www.kde.org/i18n.html
KDE-Standards: http://www.kde.org/standards.html
Qt: http://www.troll.no/

FTP-Server

KDE: ftp://ftp.kde.org/
KDE-upload: ftp://upload.kde.org/

Mailing-Listen

kde: Allgemeines Diskussionsforum.
kde-announce: Ankündigungen neuer Versionen und Applikationen.
kde-user: Hilfestellungen für Anwender.
kde-devel: Hilfestellungen für Programmierer (Schreibrechte müssen erst beantragt werden bei Martin Konold <konold@kde.org>).
kde-licensing: Diskussion über rechtliche Lizenzfragen.
kde-look: Diskussionen über die äußere Gestalt von KDE.

Nähere Informationen zum Subscriben in den Listen finden Sie unter http://www.kde.org/contact.html. Alte Artikel finden Sie im Archiv unter http://lists.kde.org/.