Getting Started/de: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
 
m (Korrektur h3.)
 
(9 intermediate revisions by 4 users not shown)
Line 1: Line 1:
diese Seite in: [http://doc.qt.nokia.com/4.7/gettingstartedqt.html en] ''[doc.qt.nokia.com]'', [http://developer.qt.nokia.com/wiki/GettingStartedQt_Spanish es] ''[developer.qt.nokia.com]'', [http://developer.qt.nokia.com/wiki/GettingStartedWithQtRussian ru] ''[developer.qt.nokia.com]'', [http://developer.qt.nokia.com/wiki/GettingStartedQtPolish pl] ''[developer.qt.nokia.com]'', [http://developer.qt.nokia.com/wiki/gettingStartedPortuguese pt] ''[developer.qt.nokia.com]'', [http://developer.qt.nokia.com/wiki/GettingStartedQtDutch nl] ''[developer.qt.nokia.com]''
diese Seite in: [http://doc.qt.io/qt-4.8/gettingstartedqt.html en], [http://wiki.qt.io/GettingStartedQt_Spanish es], [http://wiki.qt.io/GettingStartedWithQtRussian ru], [http://wiki.qt.io/GettingStartedQtPolish pl], [http://wiki.qt.io/gettingStartedPortuguese pt], [http://wiki.qt.io/GettingStartedQtDutch nl]


=Schnelleinstieg in die Programmierung mit Qt=


Willkommen in der Welt von Qt des Plattformübergreifenden <span class="caps">GUI</span> 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 <span class="caps">API</span> Dokumentation einzutauchen und die Informationen zu finden, die Sie für die Anwendung brauchen, die Sie entwickeln.
= Schnelleinstieg in die Programmierung mit Qt =


==Hallo Notepad==
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.
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.


[[Image:gs1.png|Texteingabefenster]]
[[Image:http://doc.qt.io/qt-4.8/images/gs1.png|Texteingabefenster]]
 
Hier ist der Code:
<code>
#include <QApplication>
#include <QTextEdit>
 
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
 
QTextEdit textEdit;
textEdit.show();


Hier ist der Code:<br /> Lassen Sie uns mal Zeile für Zeile durch den Code gehen. In den ersten beiden Zeilen binden wir die Headerdateien für [http://doc.qt.nokia.com/4.7/qapplication.html QApplication] ''[doc.qt.nokia.com]'' und [http://doc.qt.nokia.com/4.7/qtextedit.html QTextEdit] ''[doc.qt.nokia.com]'' 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.
return app.exec();
}
</code>


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.
Lassen Sie uns mal Zeile für Zeile durch den Code gehen. In den ersten beiden Zeilen binden wir die Headerdateien für [http://doc.qt.io/qt-4.8/qapplication.html QApplication] und [http://doc.qt.io/qt-4.8/qtextedit.html QTextEdit] 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 argc und argv, 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 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 [http://doc.qt.nokia.com/4.7/qmainwindow.html QMainWindow] ''[doc.qt.nokia.com]'', 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 [http://doc.qt.nokia.com/4.7/qwidget.html#show show()] ''[doc.qt.nokia.com]'' macht sie sichtbar.
Zeile 9 zeigt das Texteingabefeld auf dem Bildschirm in seinem eigenen Fenster. Da Widgets auch als Container verwendet werden können (z.B. ein [http://doc.qt.io/qt-4.8/qmainwindow.html QMainWindow], 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 [http://doc.qt.io/qt-4.8/qwidget.html#show show()] macht sie sichtbar.
 
Zeile 11 lässt [http://doc.qt.io/qt-4.8/qapplication.html QApplication] 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.
 
<code>
qmake -project
qmake
make
</code>
 
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.
 
=== Mehr erfahren ===
|''. Über |''. Hier |
| Widgets und Fenstergeometrie | [http://doc.qt.io/qt-4.8/application-windows.html Window and Dialog Widgets] |
| Ereignisse und ihre Behandlung | [http://doc.qt.io/qt-4.8/eventsandfilters.html The Event System] |
 
== Einen Beenden Knopf hinzufügen ==
In einer echten Anwendung werden Sie mehr als nur ein Widget benötigen. Wir werden nun einen [http://doc.qt.io/qt-4.8/qpushbutton.html QPushButton] unter das Texteingabefeld anbringen. Der Knopf wird die Notepad Anwendung beim Betätigen (z. B. durch das Klicken mit der Maus) beenden.
 
[[Image:http://doc.qt.io/qt-4.8/images/gs2.png|Eingabefeld mit Beenden Knopf]]
 
Lassen Sie uns mal einen Blick auf den Code werfen:
<code>
#include <QApplication>
#include <QLayout>
#include <QTextEdit>
#include <QPushButton>
 
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
 
QTextEdit *textEdit = new QTextEdit;
QPushButton *quitButton = new QPushButton("&Quit");


Zeile 11 läßt [http://doc.qt.nokia.com/4.7/qapplication.html QApplication] ''[doc.qt.nokia.com]'' 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.
QObject::connect(quitButton, SIGNAL (clicked()), qApp, SLOT (quit()));


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.<br /> 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.
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(textEdit);
layout->addWidget(quitButton);


===Mehr erfahren {| class="infotable line" ! Über ! Hier |- | Widgets und Fenstergeometrie | [http://doc.qt.nokia.com/4.7/application-windows.html Window and Dialog Widgets] ''[doc.qt.nokia.com]'' |- | Ereignisse und ihre Behandlung | [http://doc.qt.nokia.com/4.7/eventsandfilters.html The Event System] ''[doc.qt.nokia.com]'' |}===
QWidget window;
window.setLayout(&layout);


==Einen Beenden Knopf hinzufügen==
window.show();


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


[[Image:gs2.png|Eingabefeld mit Beenden Knopf]]
Zeile 13 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.


Lassen Sie uns mal einen Blick auf den Code werfen:<br /> Zeile 1 fügt [http://doc.qt.nokia.com/4.7/qtgui.html QtGui] ''[doc.qt.nokia.com]'' ein, das alle Qts <span class="caps">GUI</span> Klassen enthält.
[http://doc.qt.io/qt-4.8/qcoreapplication.html#quit quit()] ist ein Slot der [http://doc.qt.io/qt-4.8/qapplication.html QApplication], der die Anwendung beendet. [http://doc.qt.io/qt-4.8/qabstractbutton.html#clicked clicked()] ist ein Signal, das [http://doc.qt.io/qt-4.8/qpushbutton.html QPushButton] erzeugt, wenn der Knopf gedrückt wird. Die statische [http://doc.qt.io/qt-4.8/qobject.html#connect QObject::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 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.
Zeile 15 erzeugt ein [http://doc.qt.io/qt-4.8/qvboxlayout.html QVBoxLayout]. 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 [http://doc.qt.io/qt-4.8/qvboxlayout.html QVBoxLayout] die Kindelemente vertikal untereinander.


[http://doc.qt.nokia.com/4.7/qcoreapplication.html#quit quit()] ''[doc.qt.nokia.com]'' ist ein Slot der [http://doc.qt.nokia.com/4.7/qapplication.html QApplication] ''[doc.qt.nokia.com]'', der die Anwendung beendet. [http://doc.qt.nokia.com/4.7/qabstractbutton.html#clicked clicked()] ''[doc.qt.nokia.com]'' ist ein Signal, das [http://doc.qt.nokia.com/4.7/qpushbutton.html QPushButton] ''[doc.qt.nokia.com]'' erzeugt, wenn der Knopf gedrückt wird. Die statische [http://doc.qt.nokia.com/4.7/qobject.html#connect QObject::connect()] ''[doc.qt.nokia.com]'' Funktion sorgt für die Verbindung des Slots und des Signals. <span class="caps">SIGNAL</span> und <span class="caps">SLOT</span> 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 16 und 17 fügen das Texteingabefeld und den Knopf dem Layout hinzu. In Zeile 20 setzen wir das Layout eines Widgets.


Zeile 12 erzeugt ein [http://doc.qt.nokia.com/4.7/qvboxlayout.html QVBoxLayout] ''[doc.qt.nokia.com]''. 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 [http://doc.qt.nokia.com/4.7/qvboxlayout.html QVBoxLayout] ''[doc.qt.nokia.com]'' die Kindelemente vertikal untereinander.
=== Mehr erfahren ===
|''. Über |''. Hier |
| Signale und Slots | [http://doc.qt.io/qt-4.8/signalsandslots.html Signals & Slots] |
| Layouts | [http://doc.qt.io/qt-4.8/layout.html Layout Management], [http://doc.qt.io/qt-4.8/widgets-and-layouts.html Widgets and Layouts], [http://doc.qt.io/qt-4.8/examples-layouts.html Layout Examples] |
| Widgets die Qt bereitstellt | [http://doc.qt.io/qt-4.8/gallery.html Qt Widget Gallery], [http://doc.qt.io/qt-4.8/examples-widgets.html Widget Examples] |


Zeile 13 und 14 fügen das Texteingabefeld und den Knopf dem Layout hinzu. In Zeile 17 setzen wir das Layout eines Widgets.
== QWidget Unterklassen erstellen ==
Wenn der Benutzer die Anwendung beenden will ist es u. U. erwünscht einen Dialog anzuzeigen, der sicherstellt, dass der Benutzer die Anwendung tatsächlich beenden möchte. In diesem Beispiel erstellen wir eine [http://doc.qt.io/qt-4.8/qwidget.html QWidget] Unterklasse und fügen einen Slot der Klasse hinzu, den wir mit dem '''Beenden Knopf''' verknüpfen.


===Mehr erfahren {| class="infotable line" ! Über ! Hier |- | Signale und Slots | [http://doc.qt.nokia.com/4.7/signalsandslots.html Signals &amp; Slots] ''[doc.qt.nokia.com]'' |- | Layouts | [http://doc.qt.nokia.com/4.7/layout.html Layout Management] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/widgets-and-layouts.html Widgets and Layouts] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/examples-layouts.html Layout Examples] ''[doc.qt.nokia.com]'' |- | Widgets die Qt bereitstellt | [http://doc.qt.nokia.com/4.7/gallery.html Qt Widget Gallery] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/examples-widgets.html Widget Examples] ''[doc.qt.nokia.com]'' |}===
[[Image:http://doc.qt.io/qt-4.8/images/gs3.png|QWidget Unterklasse]]


==QWidget Unterklassen erstellen==
Lassen Sie uns einen Blick auf den Code werfen:
<code>
#include <QWidget>
#include <QTextEdit>
#include <QPushButton>


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 [http://doc.qt.nokia.com/4.7/qwidget.html QWidget] ''[doc.qt.nokia.com]'' Unterklasse und fügen einen Slot der Klasse hinzu, den wir mit dem '''Beenden Knopf''' verknüpfen.
class Notepad : public QWidget
{
Q_OBJECT


[[Image:gs3.png|QWidget Unterklasse]]
public:
Notepad();


Lassen Sie uns einen Blick auf den Code werfen:<br /> Das Q_OBJECT Makro muß an erster Stelle einer Klassendefinition stehen; es deklariert unsere Klasse als [http://doc.qt.nokia.com/4.7/qobject.html QObject] ''[doc.qt.nokia.com]'' (natürlich muß sie auch vom QObject abgeleitet werden). Ein [http://doc.qt.nokia.com/4.7/qobject.html QObject] ''[doc.qt.nokia.com]'' 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.
private slots:
void quit();
 
private:
QTextEdit  *textEdit;
QPushButton *quitButton;
};
</code>
 
Das Q_OBJECT Makro muss an erster Stelle einer Klassendefinition stehen; es deklariert unsere Klasse als [http://doc.qt.io/qt-4.8/qobject.html QObject] (natürlich muss sie auch vom QObject abgeleitet werden). Ein [http://doc.qt.io/qt-4.8/qobject.html QObject] 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).
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.<br /> 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.
Anstatt in der main() Funktion die Benutzeroberfläche zu erstellen und den Slot zu verbinden, benutzen wir Notepads Konstruktor.
<code>
#include "notepad.h"
#include <QApplication>
 
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"));
}
</code>
 
<code>
void Notepad::quit()
{
qApp->quit();
}
</code>
 
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 [http://doc.qt.io/qt-4.8/qobject.html#tr 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.
 
=== Mehr erfahren ===
|''. Über |''. Hier |
| tr() und Internationalisierung | [http://doc.qt.io/qt-4.8/linguist-manual.html Qt Linguist Manual], [http://doc.qt.io/qt-4.8/i18n-source-translation.html Writing Source Code for Translation], [http://doc.qt.io/qt-4.8/linguist-hellotr.html Hello tr()] Example, [http://doc.qt.io/qt-4.8/internationalization.html Internationalization with Qt] |
| [http://doc.qt.io/qt-4.8/qobject.html QObjects] und das Qt Object Model (Essenziell um Qt zu verstehen) | [http://doc.qt.io/qt-4.8/object.html Object Model] |
| qmake und das Qt Erstellungssystem | [http://doc.qt.io/qt-4.8/qmake-manual.html qmake Manual] |
 
== Eine .pro Datei erstellen ==
In diesem Beispiel erstellen wir unsere eigene .pro Datei, anstatt uns eine durch
qmake -project Option generieren zu lassen.
<code>
HEADERS = notepad.h
SOURCES = notepad.cpp main.cpp
</code>
 
Die folgenden Kommandozeilen Kommandos erstellen die Beispielanwendung.
<code>
qmake
make
</code>
 
== Die Verwendung eines QMainWindow ==
Viele Anwendungen werden durch die Verwendung von [http://doc.qt.io/qt-4.8/qmainwindow.html QMainWindow] profitieren, das ihr eigenes Layout hat dem Sie eine Menüleiste, Dockwidgets, Werkzeugleisten und eine Statusleiste hinzufügen können. [http://doc.qt.io/qt-4.8/qmainwindow.html QMainWindow] besitzt einen zentralen Bereich, der durch beliebiges Widget besetzt werden kann. In unserem Fall werden wir unser Texteingabefeld dort platzieren.
 
[[Image:http://doc.qt.io/qt-4.8/images/gs4.png|QMainWindow]]
 
Lassen Sie uns einen Blick auf die neue Notepad Klassendefinition werfen:
<code>
#include <QMainWindow>
#include <QTextEdit>
#include <QAction>
#include <QMenu>
 
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;


Nun benutzen wir die [http://doc.qt.nokia.com/4.7/qobject.html#tr tr()] ''[doc.qt.nokia.com]'' 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.
QMenu *fileMenu;
};
</code>


===Mehr erfahren {| class="infotable line" ! Über ! Hier |- | tr() und Internationalisierung | [http://doc.qt.nokia.com/4.7/linguist-manual.html Qt Linguist Manual] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/i18n-source-translation.html Writing Source Code for Translation] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/linguist-hellotr.html Hello tr()] ''[doc.qt.nokia.com]'' Example, [http://doc.qt.nokia.com/4.7/internationalization.html Internationalization with Qt] ''[doc.qt.nokia.com]'' |- | [http://doc.qt.nokia.com/4.7/qobject.html QObjects] ''[doc.qt.nokia.com]'' und das Qt Object Model (Essenziell um Qt zu verstehen) | [http://doc.qt.nokia.com/4.7/object.html Object Model] ''[doc.qt.nokia.com]'' |- | qmake und das Qt Erstellungssystem | [http://doc.qt.nokia.com/4.7/qmake-manual.html qmake Manual] ''[doc.qt.nokia.com]'' |}===
Wir fügen zwei weitere Slots hinzu, die ein Dokument speichern und schließen. Wir werden diese im nächsten Abschnitt implementieren.


==Eine .pro Datei erstellen==
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 [http://doc.qt.io/qt-4.8/qaction.html QAction] bereit, die mehreren Widgets zugewiesen werden kann und mit einem Slot verbunden werden. Es können zum Beispiel sowohl [http://doc.qt.io/qt-4.8/qmenu.html QMenu] als auch [http://doc.qt.io/qt-4.8/qtoolbar.html QToolBar] Menüeinträge erzeugen unter Verwendung der gleichen [http://doc.qt.io/qt-4.8/qaction.html QActions]. Wir werden in Kürze sehen wie das funktioniert.


In diesem Beispiel erstellen wir unsere eigene .pro Datei, anstatt uns eine durch<br /> qmake -project Option generieren zu lassen.<br /> Die folgenden Kommandozeilen Kommandos erstellen die Beispielanwendung.<br /> h2. Die Verwendung eines QMainWindow
Wie zuvor benutzen wir Notepads Konstruktur um die Benutzeroberfläche zu erstellen.
<code>
#include "notepad.h"
#include <QMenuBar>


Viele Anwendungen werden durch die Verwendung von [http://doc.qt.nokia.com/4.7/qmainwindow.html QMainWindow] ''[doc.qt.nokia.com]'' ###########, das ihr eigenes Layout hat dem Sie eine Menüleiste, Dockwidgets, Werkzeugleisten und eine Statusleiste hinzufügen können. [http://doc.qt.nokia.com/4.7/qmainwindow.html QMainWindow] ''[doc.qt.nokia.com]'' besitzt einen zentralen Bereich, der durch beliebiges Widget besetzt werden kann. In unserem Fall werden wir unser Texteingabefeld dort platzieren.
Notepad::Notepad()
{
openAction = new QAction(tr("&Open"), this);
saveAction = new QAction(tr("&Save"), this);
exitAction = new QAction(tr("E&xit"), this);


[[Image:gs4.png|QMainWindow]]
connect(openAction, SIGNAL (triggered()), this, SLOT (open()));
connect(saveAction, SIGNAL (triggered()), this, SLOT (save()));
connect(exitAction, SIGNAL (triggered()), this, SLOT (quit()));


Lassen Sie uns einen Blick auf die neue Notepad Klassendefinition werfen:<br /> Wir fügen zwei weitere Slots hinzu, die ein Dokument speichern und schließen. Wir werden diese im nächsten Abschnitt implementieren.
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(openAction);
fileMenu->addAction(saveAction);
fileMenu->addSeparator();
fileMenu->addAction(exitAction);


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 [http://doc.qt.nokia.com/4.7/qaction.html QAction] ''[doc.qt.nokia.com]'' bereit, die mehreren Widgets zugewiesen werden kann und mit einem Slot verbunden werden. Es können zum Beispiel sowohl [http://doc.qt.nokia.com/4.7/qmenu.html QMenu] ''[doc.qt.nokia.com]'' als auch [http://doc.qt.nokia.com/4.7/qtoolbar.html QToolBar] ''[doc.qt.nokia.com]'' Menüeinträge erzeugen unter Verwendung der gleichen [http://doc.qt.nokia.com/4.7/qaction.html QActions] ''[doc.qt.nokia.com]''. Wir werden in Kürze sehen wie das funktioniert.
textEdit = new QTextEdit;
setCentralWidget(textEdit);


Wie zuvor benutzen wir Notepads Konstruktur um die Benutzeroberfläche zu erstellen.<br /> “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 [http://doc.qt.nokia.com/4.7/qicon.html Icon] ''[doc.qt.nokia.com]'' zuweisen können.
setWindowTitle(tr("Notepad"));
}
</code>
[http://doc.qt.io/qt-4.8/qaction.html QActions] 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 [http://doc.qt.io/qt-4.8/qicon.html Icon] zuweisen können.


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


===Mehr erfahren {| class="infotable line" ! Über ! Hier |- | Hauptanwendungsfenster und Hauptfensterklassen | [http://doc.qt.nokia.com/4.7/mainwindow.html Application Main Window] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/examples-mainwindow.html Main Window Examples] ''[doc.qt.nokia.com]'' |- | <span class="caps">MDI</span> applications | [http://doc.qt.nokia.com/4.7/qmdiarea.html QMdiArea] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/mainwindows-mdi.html <span class="caps">MDI</span> Example] ''[doc.qt.nokia.com]'' |}===
=== Mehr erfahren ===
|''. Über |''. Hier |
| Hauptanwendungsfenster und Hauptfensterklassen | [http://doc.qt.io/qt-4.8/mainwindow.html Application Main Window], [http://doc.qt.io/qt-4.8/examples-mainwindow.html Main Window Examples] |
| MDI applications | [http://doc.qt.io/qt-4.8/qmdiarea.html QMdiArea], [http://doc.qt.io/qt-4.8/mainwindows-mdi.html MDI Example] |
 
== 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.


==Speichern und Laden==
[[Image:http://doc.qt.io/qt-4.8/images/gs5.png|Öffnen Dialog]]


In diesem Beispiel werden wir die Funktionalität der open() und save() Slots implementieren, die wir im vorherigen Beispiel eingeführt haben.
Wir werden mit dem open() Slot beginnen:
<code>
#include <QFileDialog>
#include <QMessageBox>
void Notepad::open()
{
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();
}
}
</code>
 
Der erste Schritt ist den Benutzer nach dem Dateinamen der Datei zu fragen, die er öffnen möchte. Qt stellt dafür ein [http://doc.qt.io/qt-4.8/qfiledialog.html QFileDialog] bereit, der einen Dialog darstellt in dem der Benutzer eine Datei auswählen kann. Das obere Bild zeigt den Dialog unter Kubuntu. Die statische [http://doc.qt.io/qt-4.8/qfiledialog.html#getOpenFileName 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 [http://doc.qt.io/qt-4.8/qiodevice.html#open 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 [http://doc.qt.io/qt-4.8/qmessagebox.html QMessageBox] um einen Dialog mit einer Fehlermeldung anzuzeigen (siehe die [http://doc.qt.io/qt-4.8/qmessagebox.html QMessageBox] Klassen Beschreibung für weitere Details).
 
Es ist recht einfach die Daten mit der Funktion [http://doc.qt.io/qt-4.8/qiodevice.html#readAll readAll()] einzulesen, die alle Daten einer Datei in einem [http://doc.qt.io/qt-4.8/qbytearray.html QByteArray] zurück gibt. Die [http://doc.qt.io/qt-4.8/qbytearray.html#constData constData()] Funktion gibt alle Daten in einem const char''' Array zurück, zu dem [http://doc.qt.io/qt-4.8/qstring.html QString] einen Konstruktor bereit stellt. Der Inhalt kann danach im Texteingabefeld angezeigt werden. Danach schließen wir die Datei mittels [http://doc.qt.io/qt-4.8/qiodevice.html#close close()] Funktion, um den Dateidescriptor an das Betriebssystem zu übergeben.
 
Lassen Sie uns nun zum save() Slot übergehen.
<code>
#include <QFileDialog>
#include <QTextStream>
void Notepad::save()
{
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "",
tr("Text Files (*.txt);;C++ Files (*.cpp *.h)"));


[[Image:gs5.png|Öffnen Dialog]]
if (fileName != "") {
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly)) {
// error message
} else {
QTextStream stream(&file);
stream << textEdit->toPlainText();
stream.flush();
file.close();
}
}
}
</code>


Wir werden mit dem open() Slot beginnen:<br /> Der erste Schritt ist den Benutzer nach dem Dateinamen der Datei zu fragen, die er öffnen möchte. Qt stellt dafür ein [http://doc.qt.nokia.com/4.7/qfiledialog.html QFileDialog] ''[doc.qt.nokia.com]'' bereit, der einen Dialog darstellt in dem der Benutzer eine Datei auswählen kann. Das obere Bild zeigt den Dialog unter Kubuntu. Die statische [http://doc.qt.nokia.com/4.7/qfiledialog.html#getOpenFileName getOpenFileName()] ''[doc.qt.nokia.com]'' 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.
Um den Inhalt des Texteingabefeldes zurück in die Datei zu schreiben verwenden wir die [http://doc.qt.io/qt-4.8/qtextstream.html QTextStream] Klasse, die das [http://doc.qt.io/qt-4.8/qfile.html QFile] Objekt umhüllt. Textstream kann QStrings direkt in eine Datei schreiben; [http://doc.qt.io/qt-4.8/qfile.html QFile] akzeptiert nur rohe Daten (char*) mit der [http://doc.qt.io/qt-4.8/qiodevice.html#write write()] Funktion des [http://doc.qt.io/qt-4.8/qiodevice.html QIODevice].


Sobald wir einen Dateinamen haben versuchen wir die Datei mittels [http://doc.qt.nokia.com/4.7/qiodevice.html#open open()] ''[doc.qt.nokia.com]'' 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 [http://doc.qt.nokia.com/4.7/qmessagebox.html QMessageBox] ''[doc.qt.nokia.com]'' um einen Dialog mit einer Fehlermeldung anzuzeigen (siehe die [http://doc.qt.nokia.com/4.7/qmessagebox.html QMessageBox] ''[doc.qt.nokia.com]'' Klasse Beschreibung für weitere Details).


Es ist recht einfach die Daten mit der Funktion [http://doc.qt.nokia.com/4.7/qiodevice.html#readAll readAll()] ''[doc.qt.nokia.com]'' einzulesen, die alle Daten einer Datei in einem [http://doc.qt.nokia.com/4.7/qbytearray.html QByteArray] ''[doc.qt.nokia.com]'' zurück gibt. Die [http://doc.qt.nokia.com/4.7/qbytearray.html#constData constData()] ''[doc.qt.nokia.com]'' Funktion gibt alle Daten in einem const char* Array zurück, zu dem [http://doc.qt.nokia.com/4.7/qstring.html QString] ''[doc.qt.nokia.com]'' einen Konstruktor bereit stellt. Der Inhalt kann danach im Texteingabefeld angezeigt werden. Danach schließen wir die Datei mittels [http://doc.qt.nokia.com/4.7/qiodevice.html#close close()] ''[doc.qt.nokia.com]'' Funktion, um den Dateidescriptor an das Betriebssystem zu übergeben.
<code>
#include <QApplication>
#include <QMessageBox>
void Notepad::quit()
{
QMessageBox messageBox;
messageBox.setWindowTitle(tr("Notepad"));
messageBox.setText(tr("Do you really want to quit?"));
messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
messageBox.setDefaultButton(QMessageBox::No);
if (messageBox.exec() == QMessageBox::Yes)
  qApp->quit();
}
</code>


Lassen Sie uns nun zum save() Slot übergehen.<br /> Um den Inhalt des Texteingabefeldes zurück in die Datei zu schreiben verwenden wir die [http://doc.qt.nokia.com/4.7/qtextstream.html QTextStream] ''[doc.qt.nokia.com]'' Klasse, die das [http://doc.qt.nokia.com/4.7/qfile.html QFile] ''[doc.qt.nokia.com]'' Objekt umhüllt. Textstream kann QStrings direkt in eine Datei schreiben; [http://doc.qt.nokia.com/4.7/qfile.html QFile] ''[doc.qt.nokia.com]'' akzeptiert nur rohe Daten (char*) mit der [http://doc.qt.nokia.com/4.7/qiodevice.html#write write()] ''[doc.qt.nokia.com]'' Funktion des [http://doc.qt.nokia.com/4.7/qiodevice.html <span class="caps">QIOD</span>evice] ''[doc.qt.nokia.com]''.
main.cpp
<code>
#include "notepad.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Notepad notepad;
notepad.show();
return app.exec();
}
</code>


===Mehr erfahren {| class="infotable line" ! Über ! Hier |- | Dateien und E/A-Geräte | [http://doc.qt.nokia.com/4.7/qfile.html QFile] ''[doc.qt.nokia.com]'', [http://doc.qt.nokia.com/4.7/qiodevice.html <span class="caps">QIOD</span>evice] ''[doc.qt.nokia.com]'' |}===


===Categories:===
=== Mehr erfahren ===
|''. Über |''. Hier |
| Dateien und E/A-Geräte | [http://doc.qt.io/qt-4.8/qfile.html QFile], [http://doc.qt.io/qt-4.8/qiodevice.html QIODevice] | ===


* [[:Category:German|German]]
[[Category:Learning]]
* [[:Category:HowTo|HowTo]]
[[Category:HowTo]]
* [[:Category:Learning|Learning]]

Latest revision as of 13:20, 7 June 2015

diese Seite in: en, es, ru, pl, pt, nl


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.

Texteingabefenster

Hier ist der Code:

#include <QApplication>
#include <QTextEdit>

int main(int argc, char *argv[])
{
 QApplication app(argc, argv);

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 und QTextEdit 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 argc und argv, 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, 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() macht sie sichtbar.

Zeile 11 lässt QApplication 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.

Mehr erfahren

|. Über |. Hier | | Widgets und Fenstergeometrie | Window and Dialog Widgets | | Ereignisse und ihre Behandlung | The Event System |

Einen Beenden Knopf hinzufügen

In einer echten Anwendung werden Sie mehr als nur ein Widget benötigen. Wir werden nun einen QPushButton unter das Texteingabefeld anbringen. Der Knopf wird die Notepad Anwendung beim Betätigen (z. B. durch das Klicken mit der Maus) beenden.

Eingabefeld mit Beenden Knopf

Lassen Sie uns mal einen Blick auf den Code werfen:

#include <QApplication>
#include <QLayout>
#include <QTextEdit>
#include <QPushButton>

int main(int argc, char *argv[])
{
 QApplication app(argc, argv);

 QTextEdit *textEdit = new QTextEdit;
 QPushButton *quitButton = new QPushButton("&Quit");

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

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

 QWidget window;
 window.setLayout(&layout);

 window.show();

 return app.exec();
}

Zeile 13 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() ist ein Slot der QApplication, der die Anwendung beendet. clicked() ist ein Signal, das QPushButton erzeugt, wenn der Knopf gedrückt wird. Die statische QObject::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 15 erzeugt ein QVBoxLayout. 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 die Kindelemente vertikal untereinander.

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

Mehr erfahren

|. Über |. Hier | | Signale und Slots | Signals & Slots | | Layouts | Layout Management, Widgets and Layouts, Layout Examples | | Widgets die Qt bereitstellt | Qt Widget Gallery, Widget Examples |

QWidget Unterklassen erstellen

Wenn der Benutzer die Anwendung beenden will ist es u. U. erwünscht einen Dialog anzuzeigen, der sicherstellt, dass der Benutzer die Anwendung tatsächlich beenden möchte. In diesem Beispiel erstellen wir eine QWidget Unterklasse und fügen einen Slot der Klasse hinzu, den wir mit dem Beenden Knopf verknüpfen.

QWidget Unterklasse

Lassen Sie uns einen Blick auf den Code werfen:

#include <QWidget>
#include <QTextEdit>
#include <QPushButton>

class Notepad : public QWidget
{
 Q_OBJECT

public:
 Notepad();

private slots:
 void quit();

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

Das Q_OBJECT Makro muss an erster Stelle einer Klassendefinition stehen; es deklariert unsere Klasse als QObject (natürlich muss sie auch vom QObject abgeleitet werden). Ein QObject 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.

#include "notepad.h"
#include <QApplication>

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"));
}
void Notepad::quit()
{
 qApp->quit();
}

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() 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.

Mehr erfahren

|. Über |. Hier | | tr() und Internationalisierung | Qt Linguist Manual, Writing Source Code for Translation, Hello tr() Example, Internationalization with Qt | | QObjects und das Qt Object Model (Essenziell um Qt zu verstehen) | Object Model | | qmake und das Qt Erstellungssystem | qmake Manual |

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

Die Verwendung eines QMainWindow

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

QMainWindow

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

#include <QMainWindow>
#include <QTextEdit>
#include <QAction>
#include <QMenu>

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 bereit, die mehreren Widgets zugewiesen werden kann und mit einem Slot verbunden werden. Es können zum Beispiel sowohl QMenu als auch QToolBar Menüeinträge erzeugen unter Verwendung der gleichen QActions. Wir werden in Kürze sehen wie das funktioniert.

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

#include "notepad.h"
#include <QMenuBar>

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

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

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

 textEdit = new QTextEdit;
 setCentralWidget(textEdit);

 setWindowTitle(tr("Notepad"));
}

QActions 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 zuweisen können.

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

Mehr erfahren

|. Über |. Hier | | Hauptanwendungsfenster und Hauptfensterklassen | Application Main Window, Main Window Examples | | MDI applications | QMdiArea, MDI Example |

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.

Öffnen Dialog

Wir werden mit dem open() Slot beginnen:

#include <QFileDialog>
#include <QMessageBox>
 
void Notepad::open()
{
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 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() 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() 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 um einen Dialog mit einer Fehlermeldung anzuzeigen (siehe die QMessageBox Klassen Beschreibung für weitere Details).

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

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

#include <QFileDialog>
#include <QTextStream>
 
void Notepad::save()
{
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(&file);
 stream << textEdit->toPlainText();
 stream.flush();
 file.close();
 }
}
}

Um den Inhalt des Texteingabefeldes zurück in die Datei zu schreiben verwenden wir die QTextStream Klasse, die das QFile Objekt umhüllt. Textstream kann QStrings direkt in eine Datei schreiben; QFile akzeptiert nur rohe Daten (char*) mit der write() Funktion des QIODevice.


#include <QApplication>
#include <QMessageBox>
 
void Notepad::quit()
{
 QMessageBox messageBox;
 messageBox.setWindowTitle(tr("Notepad"));
 messageBox.setText(tr("Do you really want to quit?"));
 messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
 messageBox.setDefaultButton(QMessageBox::No);
 
 if (messageBox.exec() == QMessageBox::Yes)
  qApp->quit();
}

main.cpp

#include "notepad.h"
#include <QApplication>
 
int main(int argc, char *argv[])
{
 QApplication app(argc, argv);
 
 Notepad notepad;
 notepad.show();
 
 return app.exec();
}


Mehr erfahren

|. Über |. Hier | | Dateien und E/A-Geräte | QFile, QIODevice | ===