Getting Started/de

From Qt Wiki
Jump to navigation Jump to search

diese Seite in: "en":http://doc.qt.nokia.com/4.7/gettingstartedqt.html, "es":http://developer.qt.nokia.com/wiki/GettingStartedQt_Spanish, "ru":http://developer.qt.nokia.com/wiki/GettingStartedWithQtRussian, "pl":http://developer.qt.nokia.com/wiki/GettingStartedQtPolish, "pt":http://developer.qt.nokia.com/wiki/gettingStartedPortuguese, "nl":http://developer.qt.nokia.com/wiki/GettingStartedQtDutch

[toc align_right="yes" depth="2"]

Schnelleinstieg in die Programmierung mit Qt

Willkommen in der Welt von Qt des Plattformübergreifenden GUI Framework. In dieser "Schnelleinstiegs"-anleitung lehren wir grundlegendes Qt Wissen durch das Implementieren einer einfachen Notepad Anwendung. Nach dem Durchlesen dieser Anleitung sind Sie soweit in die Übersichten und API Dokumentation einzutauchen und die Informationen zu finden, die Sie für die Anwendung brauchen, die Sie entwickeln.

Hallo Notepad

In diesem ersten Beispiel werden wir ein einfaches Texteingabefeld erstellen und in einem Fenster auf dem Desktop anzeigen. Das stellt das einfachste Qt Programm mit einer Benutzeroberfläche dar.

p=. Texteingabefenster

Hier ist der Code:

#include <QApplication>
#include <QTextEdit>

int main(int argv, char **args)
{
 QApplication app(argv, args);

QTextEdit textEdit;
 textEdit.show();

return app.exec();
}

Lassen Sie uns mal Zeile für Zeile durch den Code gehen. In den ersten beiden Zeilen binden wir die Headerdateien für "QApplication":http://doc.qt.nokia.com/4.7/qapplication.html und "QTextEdit":http://doc.qt.nokia.com/4.7/qtextedit.html ein, die beide Klassen darstellen, die wir für dieses Beispiel benötigen. Alle Qt Klassen haben eine Headerdatei, die den Namen der Klasse trägt.

Zeile 6 erstellt ein QApplication Objekt. Dieses Objekt behandelt anwendungsweit Ressourcen und ist notwendig für eine Qt Anwendung mit einer grafischen Benutzeroberfläche. Der Konstruktor benötigt argv und args, weil Qt ein Paar Kommandozeilenargumente entgegen nehmen kann.

Zeile 8 erstellt ein QTextEdit Objekt. Eine Texteingabefeld ist ein visuelles Element einer Benutzeroberfläche. In Qt nennen wir solche Elemente Widgets. Beispiele anderer Widgets sind Scrollbalken, Labels und Radiobuttons. Ein Widget kann auch ein Container für andere Widgets sein; ein Dialog oder ein Hauptanwendungsfenster zum Beispiel.

Zeile 9 zeigt das Texteingabefeld auf dem Bildschirm in seinem eigenen Fenster. Da Widgets auch als Container verwendet werden können (z. B. ein "QMainWindow":http://doc.qt.nokia.com/4.7/qmainwindow.html, das Toolbars, Menüs, Statuszeile und ein Paar andere Widgets), ist es möglich ein einzelnes Widget in eigenem Fenster anzuzeigen. Widgets sind standardmäßig nicht sichtbar; die Funktion "show()":http://doc.qt.nokia.com/4.7/qwidget.html#show macht sie sichtbar.

Zeile 11 läßt "QApplication":http://doc.qt.nokia.com/4.7/qapplication.html in die Ereignisschleife eintreten. Solange eine Qt Anwendung läuft werden Ereignisse generiert und an die Widgets der Anwendung gesendet. Beispiele solcher Ereignisse sind Mausklicks oder Tastatureingaben. Wenn Sie einen Text in das Texteingabefeld eintippen empfängt es Tastatureingabe Ereignisse und beantwortet diese in dem es den eingegebenen Text darstellt.

Um die Anwendung auszuführen öffnen Sie die Kommandozeile und gehen zum Verzeichnis in dem Sie die .cpp Dateien des Programms liegen haben. Folgende Shell Kommandos übersetzen und erstellen das Programm.

qmake -project
qmake
make

Das wird eine ausführbare Datei im part1 Verzeichnis erstellen (unter Windows werden Sie u. U. nmake anstatt make verwenden müssen. Ferner wird die ausführbare Datei in part1/debug oder part1/release erstellt). qmake is Qts Erstellprogramm, das eine Konfigurationsdatei entgegen nimmt. qmake erstellt diese für uns, wenn das Argument -project übergeben wird. Mit der Konfigurationsdatei (mit der Endung .pro) erstellt qmake eine make Datei, das das Programm für Sie erstellt. Wir werden uns später ansehen wie man eigene .pro Datei schreibt.

h3. Mehr erfahren |. Über |. Hier | | Widgets und Fenstergeometrie | "Window and Dialog Widgets":http://doc.qt.nokia.com/4.7/application-windows.html | | Ereignisse und ihre Behandlung | "The Event System":http://doc.qt.nokia.com/4.7/eventsandfilters.html |

h2. Einen Beenden Knopf hinzufügen

In einer echten Anwendung werden Sie mehr als nur ein Widget benötigen. Wir werden nun einen "QPushButton":http://doc.qt.nokia.com/4.7/qpushbutton.html unter das Texteingabefeld anbringen. Der Knopf wird die Notepad Anwendung beim Betätigen (z. B. durch das Klicken mit der Maus) beenden.

p=. Eingabefeld mit Beenden Knopf

Lassen Sie uns mal einen Blick auf den Code werfen:

#include <QtGui>

int main(int argv, char **args)
{
 QApplication app(argv, args);

 QTextEdit textEdit;
 QPushButton quitButton("Quit");

 QObject::connect(&amp;quitButton, SIGNAL (clicked()), qApp, SLOT (quit()));

 QVBoxLayout layout;
 layout.addWidget(&amp;textEdit);
 layout.addWidget(&amp;quitButton);

 QWidget window;
 window.setLayout(&amp;layout);

 window.show();

 return app.exec();
}

Zeile 1 fügt "QtGui":http://doc.qt.nokia.com/4.7/qtgui.html ein, das alle Qts GUI Klassen enthält.

Zeile 10 verwendet Qts Signals and Slots Mechanismus um die Anwendung beim Drücken des Beenden Knopf zu schließen. Ein Slot ist eine Funktion, die durch die Verwendung ihres Namens (in Form einer Zeichenkette) zu Laufzeit aufgerufen werden kann. Ein Signal ist eine Funktion die, wenn aufgerufen, alle dazu registrierten Slots aufruft; wir nennen es einen Slot mit einem Signal verbinden und ein Signal erzeugen.

"quit()":http://doc.qt.nokia.com/4.7/qcoreapplication.html#quit ist ein Slot der "QApplication":http://doc.qt.nokia.com/4.7/qapplication.html, der die Anwendung beendet. "clicked()":http://doc.qt.nokia.com/4.7/qabstractbutton.html#clicked ist ein Signal, das "QPushButton":http://doc.qt.nokia.com/4.7/qpushbutton.html erzeugt, wenn der Knopf gedrückt wird. Die statische "QObject::connect()":http://doc.qt.nokia.com/4.7/qobject.html#connect Funktion sorgt für die Verbindung des Slots und des Signals. SIGNAL () und SLOT() sind zwei Makros, die die Funktionssignatur des Signal bzw. Slot entgegennehmen, die verbunden werden sollen. Ferner müssen wir die Zeiger der Objekte übergeben, das das Signal sendet bzw. empfängt.

Zeile 12 erzeugt ein "QVBoxLayout":http://doc.qt.nokia.com/4.7/qvboxlayout.html. Wie bereits erwähnt können Widgets auch andere Widgets enthalten. Es ist möglich die Abgrenzungen (Größe und Position) eines Kindwidgets direkt zu setzen. Jedoch ist es einfacher ein Layout zu verwenden. Ein Layout verwaltet die Abgrenzungen der Kindwidgets. Beispielsweise positioniert "QVBoxLayout":http://doc.qt.nokia.com/4.7/qvboxlayout.html die Kindelemente vertikal untereinander.

Zeile 13 und 14 fügen das Texteingabefeld und den Knopf dem Layout hinzu. In Zeile 17 setzen wir das Layout eines Widgets.

h3. Mehr erfahren |. Über |. Hier | | Signale und Slots | "Signals & Slots":http://doc.qt.nokia.com/4.7/signalsandslots.html | | Layouts | "Layout Management":http://doc.qt.nokia.com/4.7/layout.html, "Widgets and Layouts":http://doc.qt.nokia.com/4.7/widgets-and-layouts.html, "Layout Examples":http://doc.qt.nokia.com/4.7/examples-layouts.html | | Widgets die Qt bereitstellt | "Qt Widget Gallery":http://doc.qt.nokia.com/4.7/gallery.html, "Widget Examples":http://doc.qt.nokia.com/4.7/examples-widgets.html |

h2. QWidget Unterklassen erstellen

Wenn der Benutzer die Anwendung beenden will ist es u. U. erwünscht einen Dialog anzuzeigen, der sicherstellt, daß der Benutzer die Anwendung tatsächlich beenden möchte. In diesem Beispiel erstellen wir eine "QWidget":http://doc.qt.nokia.com/4.7/qwidget.html Unterklasse und fügen einen Slot der Klasse hinzu, den wir mit dem Beenden Knopf verknüpfen.

p=. QWidget Unterklasse

Lassen Sie uns einen Blick auf den Code werfen:

class Notepad : public QWidget
{
 Q_OBJECT

public:
 Notepad();

private slots:
 void quit();

private:
 QTextEdit *textEdit;
 QPushButton *quitButton;
};

Das Q_OBJECT Makro muß an erster Stelle einer Klassendefinition stehen; es deklariert unsere Klasse als "QObject":http://doc.qt.nokia.com/4.7/qobject.html (natürlich muß sie auch vom QObject abgeleitet werden). Ein "QObject":http://doc.qt.nokia.com/4.7/qobject.html reichert eine gewöhnlichen C++ Klasse mit einigen Fähigkeiten an. Beachtenswert ist die Möglichkeit den Klassen- und die Slotnamen zur Laufzeit abfragen zu können. Darüber hinaus ist es möglich die Parametertypen eines Slots abzufragen und den Slot aufzurufen.

Zeile 13 deklariert den Slot quit(). Einfach durch das Benutzen des Slot Makros. Der quit() Slot kann nun mit den Signalen verbunden werden, die eine passende Signatur besitzen (Jedes Signal, das keine Argumente erwartet).

Anstatt in der main() Funktion die Benutzeroberfläche zu erstellen und den Slot zu verbinden, benutzen wir Notepads Konstruktor.

Notepad::Notepad()
{
 textEdit = new QTextEdit;
 quitButton = new QPushButton(tr("Quit"));

connect(quitButton, SIGNAL (clicked()), this, SLOT (quit()));

QVBoxLayout '''layout = new QVBoxLayout;
 layout->addWidget(textEdit);
 layout->addWidget(quitButton);

 setLayout(layout);

 setWindowTitle(tr("Notepad"));
}

Wie Sie in der Klassendefinition sehen konnten benutzen wir Zeiger unserer QObjects (textEdit und quitButton). In der Regel sollten Sie QObjects Objekte immer auf dem Heap erstellen und diese nie kopieren.

Nun benutzen wir die "tr()":http://doc.qt.nokia.com/4.7/qobject.html#tr Funktion um unsere sichtbaren Bezeichner. Diese Funktion ist notwendig falls Sie vorhaben Ihre Anwendung in mehreren Sprachen (z. B. Englisch und Chinesisch) bereit zu stellen. Wir werden hier jedoch nicht ins Detail gehen. Sie können dem Qt Linguist Link folgen um mehr darüber zu erfahren.

h3. Mehr erfahren |. Über |. Hier | | tr() und Internationalisierung | "Qt Linguist Manual":http://doc.qt.nokia.com/4.7/linguist-manual.html, "Writing Source Code for Translation":http://doc.qt.nokia.com/4.7/i18n-source-translation.html, "Hello tr()":http://doc.qt.nokia.com/4.7/linguist-hellotr.html Example, "Internationalization with Qt":http://doc.qt.nokia.com/4.7/internationalization.html | | "QObjects":http://doc.qt.nokia.com/4.7/qobject.html und das Qt Object Model (Essenziell um Qt zu verstehen) | "Object Model":http://doc.qt.nokia.com/4.7/object.html | | qmake und das Qt Erstellungssystem | "qmake Manual":http://doc.qt.nokia.com/4.7/qmake-manual.html |

h2. Eine .pro Datei erstellen

In diesem Beispiel erstellen wir unsere eigene .pro Datei, anstatt uns eine durch qmake -project Option generieren zu lassen.

HEADERS = notepad.h
SOURCES = notepad.cpp main.cpp

Die folgenden Kommandozeilen Kommandos erstellen die Beispielanwendung.

qmake
make

h2. Die Verwendung eines QMainWindow

Viele Anwendungen werden durch die Verwendung von "QMainWindow":http://doc.qt.nokia.com/4.7/qmainwindow.html profitieren, das ihr eigenes Layout hat dem Sie eine Menüleiste, Dockwidgets, Werkzeugleisten und eine Statusleiste hinzufügen können. "QMainWindow":http://doc.qt.nokia.com/4.7/qmainwindow.html besitzt einen zentralen Bereich, der durch beliebiges Widget besetzt werden kann. In unserem Fall werden wir unser Texteingabefeld dort platzieren.

p=. QMainWindow

Lassen Sie uns einen Blick auf die neue Notepad Klassendefinition werfen:

#include <QtGui>

class Notepad : public QMainWindow
{
 Q_OBJECT

public:
 Notepad();

private slots:
 void open();
 void save();
 void quit();

private:
 QTextEdit *textEdit;

 QAction *openAction;
 QAction *saveAction;
 QAction *exitAction;

 QMenu '''fileMenu;
};

Wir fügen zwei weitere Slots hinzu, die ein Dokument speichern und schließen. Wir werden diese im nächsten Abschnitt implementieren.

In einem Hauptfenster soll der gleiche Slot oft mehrfach, durch verschiedene Widgets, aufgerufen werden können. Beispiele dafür sind Menüeinträge und Knöpfe in der Werkzeugleiste. Um dieses zu vereinfachen stellt Qt "QAction":http://doc.qt.nokia.com/4.7/qaction.html bereit, die mehreren Widgets zugewiesen werden kann und mit einem Slot verbunden werden. Es können zum Beispiel sowohl "QMenu":http://doc.qt.nokia.com/4.7/qmenu.html als auch "QToolBar":http://doc.qt.nokia.com/4.7/qtoolbar.html Menüeinträge erzeugen unter Verwendung der gleichen "QActions":http://doc.qt.nokia.com/4.7/qaction.html. Wir werden in Kürze sehen wie das funktioniert.

Wie zuvor benutzen wir Notepads Konstruktur um die Benutzeroberfläche zu erstellen.

Notepad::Notepad()
{
 openAction = new QAction(tr("&amp;Open"), this);
 saveAction = new QAction(tr("&amp;Save"), this);
 exitAction = new QAction(tr("E&amp;amp;xit"), this);

 connect(openAction, SIGNAL (triggered()), this, SLOT (open()));
 connect(saveAction, SIGNAL (triggered()), this, SLOT (save()));
 connect(exitAction, SIGNAL (triggered()), qApp, SLOT (quit()));

 fileMenu = menuBar()->addMenu(tr("&amp;File"));
 fileMenu->addAction(openAction);
 fileMenu->addAction(saveAction);
 fileMenu->addSeparator();
 fileMenu->addAction(exitAction);

 textEdit = new QTextEdit;
 setCentralWidget(textEdit);

 setWindowTitle(tr("Notepad"));
}

"QActions"http://doc.qt.nokia.com/4.7/qaction.html werden mit dem Text erstellt, der auf dem Widget erscheinen soll, dem wir es zuweisen (in unserem Fall Menüeinträge). Falls wir sie zusätzlich auch einer Werkzeugleiste zuweisen wollten, hätten wir den Aktionen auch ein "Icon":http://doc.qt.nokia.com/4.7/qicon.html zuweisen können.

Wenn nun ein Menüeintrag geklickt wird, löst der Eintrag die Aktion aus und der dazugehörige Slot wird aktiviert.

h3. Mehr erfahren |. Über |. Hier | | Hauptanwendungsfenster und Hauptfensterklassen | "Application Main Window":http://doc.qt.nokia.com/4.7/mainwindow.html, "Main Window Examples":http://doc.qt.nokia.com/4.7/examples-mainwindow.html | | MDI applications | "QMdiArea":http://doc.qt.nokia.com/4.7/qmdiarea.html, "MDI Example":http://doc.qt.nokia.com/4.7/mainwindows-mdi.html |

h2. Speichern und Laden

In diesem Beispiel werden wir die Funktionalität der open() und save() Slots implementieren, die wir im vorherigen Beispiel eingeführt haben.

p=. Öffnen Dialog

Wir werden mit dem open() Slot beginnen:

QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "",
 tr("Text Files ('''.txt);;C++ Files ('''.cpp'''.h)"));

if (fileName != "") {
 QFile file(fileName);
 if (!file.open(QIODevice::ReadOnly)) {
 QMessageBox::critical(this, tr("Error"),
 tr("Could not open file"));
 return;
 }
 QString contents = file.readAll().constData();
 textEdit->setPlainText(contents);
 file.close();
}

Der erste Schritt ist den Benutzer nach dem Dateinamen der Datei zu fragen, die er öffnen möchte. Qt stellt dafür ein "QFileDialog":http://doc.qt.nokia.com/4.7/qfiledialog.html bereit, der einen Dialog darstellt in dem der Benutzer eine Datei auswählen kann. Das obere Bild zeigt den Dialog unter Kubuntu. Die statische "getOpenFileName()":http://doc.qt.nokia.com/4.7/qfiledialog.html#getOpenFileName Funktion zeigt einen modalen Dateidialog bis der Benutzer eine Datei ausgewählt hat. Es liefert den Dateipfad der ausgesuchten Datei zurück oder eine leere Zeichenkette, falls der Dialog abgebrochen wurde.

Sobald wir einen Dateinamen haben versuchen wir die Datei mittels "open()":http://doc.qt.nokia.com/4.7/qiodevice.html#open zu öffnen. Die open() Funktion liefert true im Erfolgsfall. Wir werden hier nicht auf die Fehlerbehandlung eingehen, auf die mehr in den "Mehr erfahren" Verknüpfungen eingegangen wird. Im Fehlerfall benutzen wir "QMessageBox":http://doc.qt.nokia.com/4.7/qmessagebox.html um einen Dialog mit einer Fehlermeldung anzuzeigen (siehe die "QMessageBox":http://doc.qt.nokia.com/4.7/qmessagebox.html Klasse Beschreibung für weitere Details).

Es ist recht einfach die Daten mit der Funktion "readAll()":http://doc.qt.nokia.com/4.7/qiodevice.html#readAll einzulesen, die alle Daten einer Datei in einem "QByteArray":http://doc.qt.nokia.com/4.7/qbytearray.html zurück gibt. Die "constData()":http://doc.qt.nokia.com/4.7/qbytearray.html#constData Funktion gibt alle Daten in einem const char Array zurück, zu dem "QString":http://doc.qt.nokia.com/4.7/qstring.html einen Konstruktor bereit stellt. Der Inhalt kann danach im Texteingabefeld angezeigt werden. Danach schließen wir die Datei mittels "close()":http://doc.qt.nokia.com/4.7/qiodevice.html#close Funktion, um den Dateidescriptor an das Betriebssystem zu übergeben.

Lassen Sie uns nun zum save() Slot übergehen.

QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "",
 tr("Text Files ('''.txt);;C++ Files ('''.cpp '''.h)"));

if (fileName != "") {
 QFile file(fileName);
 if (!file.open(QIODevice::WriteOnly)) {
 // error message
 } else {
 QTextStream stream(&amp;file);
 stream << textEdit->toPlainText();
 stream.flush();
 file.close();
 }
}

Um den Inhalt des Texteingabefeldes zurück in die Datei zu schreiben verwenden wir die "QTextStream":http://doc.qt.nokia.com/4.7/qtextstream.html Klasse, die das "QFile":http://doc.qt.nokia.com/4.7/qfile.html Objekt umhüllt. Textstream kann QStrings direkt in eine Datei schreiben; "QFile":http://doc.qt.nokia.com/4.7/qfile.html akzeptiert nur rohe Daten (char) mit der "write()":http://doc.qt.nokia.com/4.7/qiodevice.html#write Funktion des "QIODevice":http://doc.qt.nokia.com/4.7/qiodevice.html.

=== Mehr erfahren |. Über |. Hier | | Dateien und E/A-Geräte | "QFile":http://doc.qt.nokia.com/4.7/qfile.html, "QIODevice":http://doc.qt.nokia.com/4.7/qiodevice.html | ===