summaryrefslogtreecommitdiffhomepage
path: root/de-de
diff options
context:
space:
mode:
Diffstat (limited to 'de-de')
-rw-r--r--de-de/edn-de.html.markdown112
-rw-r--r--de-de/nix-de.html.markdown358
-rw-r--r--de-de/pyqt-de.html.markdown89
-rw-r--r--de-de/qt-de.html.markdown175
4 files changed, 734 insertions, 0 deletions
diff --git a/de-de/edn-de.html.markdown b/de-de/edn-de.html.markdown
new file mode 100644
index 00000000..2434d1bd
--- /dev/null
+++ b/de-de/edn-de.html.markdown
@@ -0,0 +1,112 @@
+---
+language: edn
+filename: learnedn-de.edn
+contributors:
+ - ["Jason Yeo", "https://github.com/jsyeo"]
+ - ["Jonathan D Johnston", "https://github.com/jdjohnston"]
+translators:
+ - ["Dennis Keller", "https://github.com/denniskeller"]
+lang: de-de
+---
+
+Extensible Data Notation (EDN) ist ein Format für serialisierte Daten.
+
+EDN ist ein Subset der von Clojure verwendeten Syntax. Das Lesen von Daten, die durch EDN definiert werden, ist
+sicherer als das, was durch die vollständige Clojure-Syntax definiert wird, insbesondere von nicht
+vertrauenswürdigen Quellen. EDN ist beschränkt auf Daten, kein Code. Es ist ähnlich in seinen Zielen zu JSON.
+Obwohl es mehr in Clojure verwendet wird, gibt es verschiedene Implementationen von EDN in vielen
+verschiedenen anderen Sprachen.
+
+Der Hauptvorteil von EDN im Gegensatz zu JSON und YAML ist, dass es erweiterbar ist.
+Wir werden später sehen wie es erweitert werden kann.
+
+```clojure
+; Kommentare starten mit einem Semikolon.
+; Alles nach dem Semikolon wird ignoriert.
+
+;;;;;;;;;;;;;;;;;;;
+;;; Basistypen ;;;
+;;;;;;;;;;;;;;;;;;;
+
+nil ; auch bekannt in anderen Sprachen als null
+
+; Booleans
+true
+false
+
+; Strings werden in Gänsefüßchen eingeschlossen.
+"hungarian breakfast"
+"farmer's cheesy omelette"
+
+; Charaktere werden einem Backslash vorangestellt
+\g \r \a \c \e
+
+; Schlüsselwörter beginnen mit einem Doppelpunkt. Sie verhalten sich wie Enums.
+; Ähnlich, wie Symbole in Ruby.
+:eggs
+:cheese
+:olives
+
+; Symbole werden verwendet um Identifier zu repräsentieren. Sie beginnen mit einem #.
+; Du kannst einen Namespace für Symbole nutzen, wenn du / verwendest. Egal was / vorangestellt wird
+; ist der Namespace dieses Namens.
+#spoon
+#kitchen/spoon ; nicht das selbe, wie #spoon
+#kitchen/fork
+#github/fork ; damit kannst du nicht essen
+
+; Integers und Floats
+42
+3.14159
+
+; Listen sind Sequenzen von Werten
+(:bun :beef-patty 9 "yum!")
+
+; Vektoren erlauben zufälligen Zugriff
+[:gelato 1 2 -2]
+
+; Maps sind assoziative Datenstrukturen, die einen Schlüssel mit einem Wert verbinden.
+{:eggs 2
+ :lemon-juice 3.5
+ :butter 1}
+
+; Du bist nicht beschränkt ausschließlich Schlüsselwörter als Schlüssel zu verwenden.
+{[1 2 3 4] "tell the people what she wore",
+ [5 6 7 8] "the more you see the more you hate"}
+
+; Du kannst Kommas für eine bessere Lesbarkeit verwenden. Sie werden wie Leerraum behandelt.
+; Sets sind Sammlungen, die eindeutige Elemente enthalten.
+#{:a :b 88 "huat"}
+
+;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; markierte Elemente ;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; EDN kann erweitert werden, indem Elemente mit # Symbolen makiert werden.
+
+#MyYelpClone/MenuItem {:name "eggs-benedict" :rating 10}
+
+; Lass mich das mit einem Clojure Beispiel erklären.
+; Angenommen ich möchte dieses Stück EDM in einen MenuItem record umwandeln.
+(defrecord MenuItem [name rating])
+
+; Um EDN in clojure Werte umzuwandeln, muss ich den eingebauten EDN Leser
+; edn/read-string verwenden
+
+(edn/read-string "{:eggs 2 :butter 1 :flour 5}")
+; -> {:eggs 2 :butter 1 :flour 5}
+
+; Definiere die Leserfunktion, um markierte Elemente zu transformieren
+; und übergebe eine Map, die Tags den Lesefunktionen als edn / read-string zuweisen
+
+(edn/read-string {:readers {'MyYelpClone/MenuItem map->menu-item}}
+ "#MyYelpClone/MenuItem {:name \"eggs-benedict\" :rating 10}")
+; -> #user.MenuItem{:name "eggs-benedict", :rating 10}
+
+```
+
+# Referenzen
+
+- [EDN spec](https://github.com/edn-format/edn)
+- [Implementationen](https://github.com/edn-format/edn/wiki/Implementations)
+- [makierte Elemente](http://www.compoundtheory.com/clojure-edn-walkthrough/)
diff --git a/de-de/nix-de.html.markdown b/de-de/nix-de.html.markdown
new file mode 100644
index 00000000..8c78ffbc
--- /dev/null
+++ b/de-de/nix-de.html.markdown
@@ -0,0 +1,358 @@
+---
+language: nix
+filename: learnnix-de.nix
+contributors:
+ - ["Chris Martin", "http://chris-martin.org/"]
+translators:
+ - ["Dennis Keller", "https://github.com/denniskeller"]
+lang: de-de
+---
+
+Nix ist eine simple funktionale Programmiersprache, die für den
+[Nix package manager](https://nixos.org/nix/) und
+[NixOS](https://nixos.org/) entwickelt wurde.
+
+Du kannst Nix Ausdrücke evaluieren mithilfe von
+[nix-instantiate](https://nixos.org/nix/manual/#sec-nix-instantiate)
+oder [`nix-repl`](https://github.com/edolstra/nix-repl).
+
+```
+with builtins; [
+
+ # Kommentare
+ #=========================================
+
+ # Inline Kommentare sehen so aus.
+
+ /* Multizeilen Kommentare
+ sehen so aus. */
+
+
+ # Booleans
+ #=========================================
+
+ (true && false) # Und
+ #=> false
+
+ (true || false) # Oder
+ #=> true
+
+ (if 3 < 4 then "a" else "b") # Bedingungen
+ #=> "a"
+
+
+ # Integers
+ #=========================================
+
+ # Integers sind die einzigen numerischen Typen.
+
+ 1 0 42 (-3) # Einige integers
+
+ (4 + 6 + 12 - 2) # Addition
+ #=> 20
+
+ (7 / 2) # Division
+ #=> 3
+
+
+ # Strings
+ #=========================================
+
+ "String Literale sind in Gänsefüßchen."
+
+ "
+ String Literale können mehrere
+ Zeilen umspannen.
+ "
+
+ ''
+ Dies wird als Literal mit eingerückten String bezeichnet.
+ Es entfernt intelligent führende Leerzeichen.
+ ''
+
+ ''
+ a
+ b
+ ''
+ #=> "a\n b"
+
+ ("ab" + "cd") # String Konkatenation
+ #=> "abcd"
+
+ # Mit Antiquotation kannst du Werte in Strings einbetten.
+ ("Dein Homeverzeichnis ist ${getEnv "HOME"}")
+ #=> "Dein Homeverzeichnis ist /home/alice"
+
+
+ # Paths
+ #=========================================
+
+ # Nix besitzt einen primitven Datentyp für Pfade
+ /tmp/tutorials/learn.nix
+
+ # Ein relativer Pfad wird beim Parsing zu einem absoluten Pfad aufgelöst,
+ # relativ zu der Datei in der es auftritt.
+ tutorials/learn.nix
+ #=> /the-base-path/tutorials/learn.nix
+
+ # Ein Pfad muss mindestens einen Schrägstrich enthalten. Ein Pfad für eine
+ # Datei im selben Verzeichnis benötigt ein ./ Präfix.
+ ./learn.nix
+ #=> /the-base-path/learn.nix
+
+ # Der / Operator muss von Leerraum umgeben sein wenn du dividieren möchtest.
+ 7/2 # Das ist ein Pfadliteral
+ (7 / 2) # Das ist ein Integerliteral
+
+
+ # Importe
+ #=========================================
+
+ # Eine nix Datei besitzt einen einzelnen top-level Ausdruck mit keinen freien Variablen.
+ # Ein Import-Ausdruck wird zum Wert der Datei, die importiert wird, ausgewertet.
+ (import /tmp/foo.nix)
+
+ # Importe können ebenso mit Strings spezifiziert werden.
+ (import "/tmp/foo.nix")
+
+ # Import Pfade müssen absolut sein. Pfadliterale
+ # sind automatisch aufgelöst, das ist ein Ordnung.
+ (import ./foo.nix)
+
+ # Jedoch passiert dies nicht mit Strings.
+ (import "./foo.nix")
+ #=> error: string ‘foo.nix’ doesn't represent an absolute path
+
+
+ # Let
+ #=========================================
+
+ # `let` Blöcke erlauben es uns Werte zu Variablen zu binden.
+ (let x = "a"; in
+ x + x + x)
+ #=> "aaa"
+
+ # Bindungen können auf sich gegenseitig verweisen. Die Reihenfolge spielt
+ # keine Rolle.
+ (let y = x + "b";
+ x = "a"; in
+ y + "c")
+ #=> "abc"
+
+ # Innere Bindungen überschatten Äußere.
+ (let a = 1; in
+ let a = 2; in
+ a)
+ #=> 2
+
+
+ # Funktionen
+ #=========================================
+
+ (n: n + 1) # Funktion, die 1 addiert
+
+ ((n: n + 1) 5) # Dieselbe Funktion angewendet auf 5.
+ #=> 6
+
+ # Es gibt keine spezielle Syntax für benannte Funktionen, aber sie
+ # können mit `let` Blöcken, wie jeder andere Wert auch, gebunden werden.
+ (let succ = (n: n + 1); in succ 5)
+ #=> 6
+
+ # Eine Funktion hat genau ein Argument.
+ # Mehrere Argumente können erreicht werden mithilfe von Currying.
+ ((x: y: x + "-" + y) "a" "b")
+ #=> "a-b"
+
+ # Benannte Funktionsargumente gibt es auch. Diese werden wir einführen, nachdem wir uns Sets
+ # angeschaut haben.
+
+ # Listen
+ #=========================================
+
+ # Listen werden durck eckige Klammern gekennzeichnet.
+
+ (length [1 2 3 "x"])
+ #=> 4
+
+ ([1 2 3] ++ [4 5])
+ #=> [1 2 3 4 5]
+
+ (concatLists [[1 2] [3 4] [5]])
+ #=> [1 2 3 4 5]
+
+ (head [1 2 3])
+ #=> 1
+ (tail [1 2 3])
+ #=> [2 3]
+
+ (elemAt ["a" "b" "c" "d"] 2)
+ #=> "c"
+
+ (elem 2 [1 2 3])
+ #=> true
+ (elem 5 [1 2 3])
+ #=> false
+
+ (filter (n: n < 3) [1 2 3 4])
+ #=> [ 1 2 ]
+
+
+ # Sets
+ #=========================================
+
+ # Ein "Set" ist eine ungeordnete Zuordnung mit Stringschlüsseln.
+ { foo = [1 2]; bar = "x"; }
+
+ # Der . Operator nimmt einen Wert aus dem Set.
+ { a = 1; b = 2; }.a
+ #=> 1
+
+ # Der ? Operator testet, ob der Schlüssel in dem Set vorhanden ist.
+ ({ a = 1; b = 2; } ? a)
+ #=> true
+ ({ a = 1; b = 2; } ? c)
+ #=> false
+
+ # Der // Operator mergt zwei Sets.
+ ({ a = 1; } // { b = 2; })
+ #=> { a = 1; b = 2; }
+
+ # Werte auf der rechten Seite überschrieben die Werte auf der linken Seite.
+ ({ a = 1; b = 2; } // { a = 3; c = 4; })
+ #=> { a = 3; b = 2; c = 4; }
+
+ # Das Schlüsselwort rec bezeichenet ein "rekursives Set", in der sich Attribute
+ # aufeinander beziehen können.
+ (let a = 1; in { a = 2; b = a; }.b)
+ #=> 1
+ (let a = 1; in rec { a = 2; b = a; }.b)
+ #=> 2
+
+ # Verschachetelte Sets können stückweise definiert werden.
+ {
+ a.b = 1;
+ a.c.d = 2;
+ a.c.e = 3;
+ }.a.c
+ #=> { d = 2; e = 3; }
+
+ # Die Nachkommen eines Attributs können in diesem Feld nicht zugeordnet werden, wenn
+ # das Attribut selbst nicht zugeweisen wurde.
+ {
+ a = { b = 1; };
+ a.c = 2;
+ }
+ #=> error: attribute ‘a’ already defined
+
+
+ # With
+ #=========================================
+
+ # Der Körper eines Sets Blocks wird mit der Zurodnung eines Satzes an die Variablen gebunden.
+ (with { a = 1; b = 2; };
+ a + b)
+ # => 3
+
+ # Innere Bindungen überschatten äußere Bindungen.
+ (with { a = 1; b = 2; };
+ (with { a = 5; };
+ a + b))
+ #=> 7
+
+ # Die erste Linie diese Tutorials startet mit "with builtins;",
+ # weil builtins ein Set mit allen eingebauten
+ # Funktionen (length, head, tail, filter, etc.) umfasst.
+ # Das erspart uns beispielseweise "builtins.length" zu schreiben,
+ # anstatt nur "length".
+
+
+ # Set patterns
+ #=========================================
+
+ # Sets sind nützlich, wenn du mehrere Werte einer Funktion
+ # übergeben musst.
+ (args: args.x + "-" + args.y) { x = "a"; y = "b"; }
+ #=> "a-b"
+
+ # Dies kann mit Hilfe von Set patterns deutlicher geschrieben werden.
+ ({x, y}: x + "-" + y) { x = "a"; y = "b"; }
+ #=> "a-b"
+
+ # Standardmäßig schlägt das Muster bei Sets mit zusätzlichen Schlüsseln fehl.
+ ({x, y}: x + "-" + y) { x = "a"; y = "b"; z = "c"; }
+ #=> error: anonymous function called with unexpected argument ‘z’
+
+ # Durch Hinzufügen von ", ..." können zusätzliche Schlüssel ignoriert werden.
+ ({x, y, ...}: x + "-" + y) { x = "a"; y = "b"; z = "c"; }
+ #=> "a-b"
+
+
+ # Errors
+ #=========================================
+
+ # `throw` bewirkt, dass die Auswertung mit einer Fehlermeldung abgebrochen wird.
+ (2 + (throw "foo"))
+ #=> error: foo
+
+ # `tryEval` fängt geworfene Fehler.
+ (tryEval 42)
+ #=> { success = true; value = 42; }
+ (tryEval (2 + (throw "foo")))
+ #=> { success = false; value = false; }
+
+ # `abort` ist ähnlich wie throw, aber es ist fatal. Es kann nicht gefangen werden.
+ (tryEval (abort "foo"))
+ #=> error: evaluation aborted with the following error message: ‘foo’
+
+ # `assert` evaluiert zu dem gegebenen Wert, wenn die Bedingung wahr ist, sonst
+ # löst es eine abfangbare Exception aus.
+ (assert 1 < 2; 42)
+ #=> 42
+ (assert 1 > 2; 42)
+ #=> error: assertion failed at (string):1:1
+ (tryEval (assert 1 > 2; 42))
+ #=> { success = false; value = false; }
+
+
+ # Impurity
+ #=========================================
+
+ # Da die Wiederholbarkeit von Builds für den Nix Packetmangager entscheidend ist,
+ # werden in der Nix Sprache reine funktionale Elemente betont. Es gibt aber ein paar
+ # unreine Elemente.
+ # Du kannst auf Umgebungsvarialben verweisen.
+ (getEnv "HOME")
+ #=> "/home/alice"
+
+ # Die trace Funktion wird zum Debugging verwendet. Sie gibt das erste Argument zu stderr aus
+ # und evaluiert das zweite Argument.
+ (trace 1 2)
+ #=> trace: 1
+ #=> 2
+
+ # Du kannst Dateien in den Nix store schreiben. Obwohl unrein, kannst du dir relativ sicher sein,
+ # dass es sicher ist, da der Dateiname aus dem Hash des Inhalts abgeleitet wird.
+ # Du kannst Dateien von überall lesen. In diesem Beispiel schreiben wir Dateien in den Store
+ # und lesen wieder davon.
+ (let filename = toFile "foo.txt" "hello!"; in
+ [filename (builtins.readFile filename)])
+ #=> [ "/nix/store/ayh05aay2anx135prqp0cy34h891247x-foo.txt" "hello!" ]
+
+ # Außerdem können wir Dateien in den Nix Store downloaden.
+ (fetchurl "https://example.com/package-1.2.3.tgz")
+ #=> "/nix/store/2drvlh8r57f19s9il42zg89rdr33m2rm-package-1.2.3.tgz"
+
+]
+```
+
+### Weitere Resourcen
+
+* [Nix Manual - Nix expression language]
+ (https://nixos.org/nix/manual/#ch-expression-language)
+
+* [James Fisher - Nix by example - Part 1: The Nix expression language]
+ (https://medium.com/@MrJamesFisher/nix-by-example-a0063a1a4c55)
+
+* [Susan Potter - Nix Cookbook - Nix By Example]
+ (http://funops.co/nix-cookbook/nix-by-example/)
diff --git a/de-de/pyqt-de.html.markdown b/de-de/pyqt-de.html.markdown
new file mode 100644
index 00000000..93ee20d4
--- /dev/null
+++ b/de-de/pyqt-de.html.markdown
@@ -0,0 +1,89 @@
+---
+category: tool
+tool: PyQT
+filename: learnpyqt-de.py
+contributors:
+ - ["Nathan Hughes", "https://github.com/sirsharpest"]
+translators:
+ - ["Dennis Keller", "https://github.com/denniskeller"]
+lang: de-de
+---
+
+**Qt** ist eine weit bekanntes Framework mit den man plattformunabhängige Programme schreiben kann,
+die auf verschiedenen Sotfware und Hardware Plattformen laufen mit kleinen oder keinen Änderungen im Code.
+Dabei besitzen sie trozdem die Power und Geschwindigkeit von nativen Anwendungen.
+**Qt** wurde ursprünglich in *C++** geschrieben.
+
+Das ist eine Adaption von dem C++ Intro für QT von [Aleksey Kholovchuk](https://github.com/vortexxx192),
+manche der Codebeispiele sollte in der selben Funktionalität resultieren.
+Diese Version wurde in pyqt erstellt.
+
+```python
+import sys
+from PyQt4 import QtGui
+
+def window():
+ # Erschafft ein Anwendungsobjekt.
+ app = QtGui.QApplication(sys.argv)
+ # Erschafft ein Widget, auf dem unser Label platziert wird.
+ w = QtGui.QWidget()
+ # Fügt ein Label zu dem Widget hinzu.
+ b = QtGui.QLabel(w)
+ # Setzt einen Text für das Label.
+ b.setText("Hello World!")
+ # Setzt die Größe und die Platzierungsinfomationen.
+ w.setGeometry(100, 100, 200, 50)
+ b.move(50, 20)
+ # Setzt unserem Fenster einen schönen Titel.
+ w.setWindowTitle("PyQt")
+ # Lässt alles anzeigen.
+ w.show()
+ # Führe alles aus, nachdem wir alles aufgebaut haben.
+ sys.exit(app.exec_())
+
+if __name__ == '__main__':
+ window()
+
+```
+
+Damit wir weitere fortgeschrittene Funktionen in **pyqt** verwenden können,
+müssen wir anfangen zusätzliche Elemente zu bauen.
+Hier zeigen wir wie man eine Dialog Popup Box einführt.
+Diese ist nützlich, um den Benutzer eine Entscheidung zu bestätigen oder um Informationen anzuzeigen.
+
+```Python
+import sys
+from PyQt4.QtGui import *
+from PyQt4.QtCore import *
+
+
+def window():
+ app = QApplication(sys.argv)
+ w = QWidget()
+ # Erschafft einen Knopf und fügt das Widget w hinzu
+ b = QPushButton(w)
+ b.setText("drücke mich")
+ b.move(50, 50)
+ # Wenn b gedrückt wird, wird diese Funktion aufgerufen.
+ # Bemerke das Fehlen von () bei dem Funktionsaufruf.
+ b.clicked.connect(showdialog)
+ w.setWindowTitle("PyQt Dialog")
+ w.show()
+ sys.exit(app.exec_())
+
+# Diese Funktion soll ein Dialogfenster mit einem Knopf erschaffen.
+# Der Knopf wartet bis er geklickt wird und beendet das Programm
+def showdialog():
+ d = QDialog()
+ b1 = QPushButton("ok", d)
+ b1.move(50, 50)
+ d.setWindowTitle("Dialog")
+ # Diese Modalität sagt dem Popup, dass es den Parent blocken soll, solange es aktiv ist.
+ d.setWindowModality(Qt.ApplicationModal)
+ # Beim klicken möchte ich, dass der gesamte Prozess beendet wird.
+ b1.clicked.connect(sys.exit)
+ d.exec_()
+
+if __name__ == '__main__':
+ window()
+```
diff --git a/de-de/qt-de.html.markdown b/de-de/qt-de.html.markdown
new file mode 100644
index 00000000..480030fe
--- /dev/null
+++ b/de-de/qt-de.html.markdown
@@ -0,0 +1,175 @@
+---
+category: tool
+tool: Qt Framework
+language: c++
+filename: learnqt-de.cpp
+contributors:
+ - ["Aleksey Kholovchuk", "https://github.com/vortexxx192"]
+translators:
+ - ["Dennis Keller", "https://github.com/denniskeller"]
+lang: de-de
+---
+
+**Qt** ist ein weithin bekanntes Framework zum Entwickeln von cross-platform Software,
+die auf verschiedenen Hard- und Softwareplatformen mit wenig oder keinen Veränderungen im Code läuft.
+Dabei besitzt man die Power und Geschiwindigkeit von nativen Anwendungen.
+Obwohl **Qt** ursprünglich in *C++* geschrieben wurde,
+gibt es verschiedene Ports für andere Sprachen: *[PyQt](https://learnxinyminutes.com/docs/pyqt/)*, *QtRuby*, *PHP-Qt*, etc.
+
+**Qt** eignet sich hervorragend zum Erstellen von Anwendungen mit grafischer Benutzeroberfläche (GUI).
+Dieses Tutorial zeigt, wie man das in *C++* macht.
+
+```c++
+/*
+ * Lass uns klassisch starten
+ */
+
+// Alle Header vom Qt Framework starten mit dem Großbuchstaben 'Q'.
+#include <QApplication>
+#include <QLineEdit>
+
+int main(int argc, char *argv[]) {
+ // Erstellt ein Objekt um applikationsweit die Resourcen zu managen.
+ QApplication app(argc, argv);
+
+ // Erstellt ein Line edit Widget und zeigt es auf dem Bildschirm
+ QLineEdit lineEdit("Hello world!");
+ lineEdit.show();
+
+ // Startet die Event Loop der Anwendung.
+ return app.exec();
+}
+```
+
+Die GUI bezogene Teile von **Qt** bestehen aus *Widgets* und den *Verbindungen*
+dazwischen.
+
+[Lies mehr über Widgets](http://doc.qt.io/qt-5/qtwidgets-index.html)
+
+```c++
+/*
+ * Lass uns Label und einen Button machen.
+ * Ein Label soll auftauchen, wenn der Button gedrückt wird.
+ *
+ * Der Qt Code spricht für sich selbst.
+ */
+
+#include <QApplication>
+#include <QDialog>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QLabel>
+
+int main(int argc, char *argv[]) {
+ QApplication app(argc, argv);
+
+ QDialog dialogWindow;
+ dialogWindow.show();
+
+ // Füge ein vertikales Layout hinzu
+ QVBoxLayout layout;
+ dialogWindow.setLayout(&layout);
+
+ QLabel textLabel("Danke für das Knopf drücken");
+ layout.addWidget(&textLabel);
+ textLabel.hide();
+
+ QPushButton button("Drück mich");
+ layout.addWidget(&button);
+
+ // Zeigt verstecktes Label, wenn der Button gedrückt wird.
+ QObject::connect(&button, &QPushButton::pressed,
+ &textLabel, &QLabel::show);
+
+ return app.exec();
+}
+```
+
+Beachte den *QObject::connect* Teil. Diese Methode wird verwendet,
+um *Signale* eines Objekts mit den *Slots* eines Objektes zu verbinden.
+
+**Signale** werden ausgegeben, wenn bestimmte Dinge mit Objekten passieren.
+Beispielsweise wird das *pressed* Signal ausgegeben,
+wenn der Benutzer auf das QPushButton Objekt drückt.
+
+**Slots** sind Aktionen, die als Reaktion auf empfangene Signale ausgeführt werden können.
+
+[Lies mehr über Slots und Signale](http://doc.qt.io/qt-5/signalsandslots.html)
+
+
+Als Nächstes lernen wir, dass wir nicht nur Standard Widgets verwenden können,
+sondern auch ihr Verhalten mithilfe von Vererbung verändern können.
+Lass uns einen Button erschaffen, der zählt, wie häufig er gedrückt wird.
+Dafür definieren wir unsere eigene Klasse *CounterLabel*.
+Diese muss wegen der speziellen Qt Architektur in einer seperaten Datei deklariert werden.
+
+```c++
+// counterlabel.hpp
+
+#ifndef COUNTERLABEL
+#define COUNTERLABEL
+
+#include <QLabel>
+
+class CounterLabel : public QLabel {
+ Q_OBJECT // Qt definiertes Makro, welches in jedem modifizierten Widget vorhanden sein muss.
+
+public:
+ CounterLabel() : counter(0) {
+ setText("Zähler wurde noch nicht erhöht."); // Methode von QLabel
+ }
+
+public slots:
+ // Aktion, die ausgeführt wird, wenn der Button gedrückt wird.
+ void increaseCounter() {
+ setText(QString("Zähler Wert: %1").arg(QString::number(++counter)));
+ }
+
+private:
+ int counter;
+};
+
+#endif // Zähllabel
+```
+
+```c++
+// main.cpp
+// Fast das Gleiche, wie das vorherige Beispiel
+
+#include <QApplication>
+#include <QDialog>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QString>
+#include "counterlabel.hpp"
+
+int main(int argc, char *argv[]) {
+ QApplication app(argc, argv);
+
+ QDialog dialogWindow;
+ dialogWindow.show();
+
+ QVBoxLayout layout;
+ dialogWindow.setLayout(&layout);
+
+ CounterLabel counterLabel;
+ layout.addWidget(&counterLabel);
+
+ QPushButton button("Drück mich nochmal.");
+ layout.addWidget(&button);
+ QObject::connect(&button, &QPushButton::pressed,
+ &counterLabel, &CounterLabel::increaseCounter);
+
+ return app.exec();
+}
+```
+
+Das wars! Natürlich ist das Qt Framework erheblich größer, als der der Teil der in diesem Tutorial behandelt wurde.
+Das heißt, es gibt viel zu lesen und zu üben.
+
+## Further reading
+
+- [Qt 4.8 tutorials](http://doc.qt.io/qt-4.8/tutorials.html)
+- [Qt 5 tutorials](http://doc.qt.io/qt-5/qtexamplesandtutorials.html)
+
+Viel Erfolg und viel Spaß!