Qt für C++ Anfänger: Die erste Version

Die Funktion addAB() Bearbeiten

Jetzt muss noch die Funktion addAB() implementiert werden und unser Taschenrechner ist in der ersten Version fertig. Die Implementation dieser Funktion besteht im Wesentlichen im Aufruf von Qt Funktionen. Hierbei kann man also ein bisschen üben, sich in der Qt Dokumentation zurecht zu finden.

Auslesen der Felder Bearbeiten

Als erstes müssen wir die Eingabefelder auslesen. Die Eingabefelder sind QLineEdit Objekte. Wir suchen also eine Funktion in der Doku zu QLineEdit, die passen könnte. Wir finden die passenden Funktionen displayText() und text(). Beide Funktionen sind gleich, ein Unterschied ergibt sich lediglich in dem Fall, dass das Eingabefeld zur Eingabe von Passworten verwendet wird. Wir entscheiden uns für text(). Die Syntax für text() ist:

QString text() const

Man ruft die Funktion also ohne Parameterübergabe auf und bekommt einen QString zurück. Das "const" am Ende der Syntaxdefinition besagt, daß das Objekt, auf das man die Funktion anwendet (also QLineEdit und damit der darin gespeicherte Text) nicht verändert wird. Wie schon beim Setzen der Default-Werte wird die Funktion über den Operator "->" aufgerufen, da es sich bei InputA um einen Pointer handelt.

QString a;
a = InputA -> text();

Jetzt haben wir in dem QString a den eingegebenen Text stehen. Analoges kann man für InputB machen. Um mit den Zahlen rechnen zu können, müssen wir aus dem QString ein Double machen.

QString in Double wandeln Bearbeiten

Um eine entsprechende Funktion zu finden, müssen wir jetzt die Doku zu QString nach einer passenden Funktion durchsuchen. Die passende Funktion ist toDouble(). Die Syntax hier ist etwas komplizierter:

double QString::toDouble ( bool * ok = 0 ) const

Man sieht direkt, dass der Rückgabewert ein double ist. Als Parameter zum Aufruf kann ein Pointer (*) auf eine boolsche Variable mitgegeben werden, die den internen Namen "ok" bekommt. Der Parameter ist optional. Das heißt, wenn kein Parameter vorhanden ist, wird der Default-Wert "0" übergeben. In dieser boolschen Variable finden wir später das Ergebnis, ob die Konvertierung also geklappt hat (ok=true) oder nicht (ok=false). Das "const" besagt wieder, dass das Objekt, auf das die Funktion angewendet wird, nicht verändert wird. In diesem Fall existiert also der QString, den wir in Double umwandeln, auch nach der Wandlung noch unverändert.

double a;
a = (InputA -> text()).toDouble();

Hier wird jetzt nicht der "->" Operator verwendet, da text() einen QString zurückliefert und nicht einen Pointer auf einen QString. Wollen wir die Wandlung prüfen, so müsste der Code so aussehen:

double a;
bool ok;
a = (InputA -> text()).toDouble(&ok);

ok ist eine boolsche Variable, die Funktion will aber einen Pointer auf eine boolsche Variable haben, sprich die (Speicher-)Adresse, wo die boolsche Variable zu finden ist. Die Adresse einer Funktion wird über den "&" Operator bestimmt. Wir werden die erste Version ohne Prüfung verwenden, auch wenn es schlechter Stil ist. Unser Code sieht also dann wie folgt aus:

double a, b, c;
a = (InputA -> text()).toDouble();
b = (InputB -> text()).toDouble();
c = a + b;

Als nächstes muss c in das QLineEdit Feld ResultC geschrieben werden. Das Problem ist, dass die bekannte Funktion setText() einen QString als Parameter erwartet und kein Double. Es muss also wieder eine Umwandlung vorgenommen werden.

Wandeln von Double nach QString Bearbeiten

Da wir wieder etwas mit einem QString machen wollen, müssen wir wieder die Doku zu QString durchsuchen. Die Funktion, die wir benötigen, lautet: arg(). Die Funktion arg() gibt es in der Dokumentation zu QString mehrfach. Dies sind so genannte überladene Funktionen. Der Compiler sucht sich an Hand der Parameter (Anzahl und Typen) die passende Funktion heraus. Wir müssen also die richtigen Parameter übergeben. Die Funktion, die wir brauchen, ist

QString QString::arg ( double a, int fieldWidth = 0, char format = 'g', 
                     int precision = -1, 
                     const QChar & fillChar = QLatin1Char( ' ' ) ) const

Warum gerade diese? Nunja, das ist die einzige, die als Übergabeparameter ein Double erlaubt. Die Funktionssyntax sieht relativ kompliziert aus. Der einzige verpflichtende Parameter ist jedoch "double a", alle anderen Übergabeparameter sind optional, da dort ein Defaultwert angegeben ist. Hierbei ist zu beachten, dass man bei der Übergabe eines Parameters, der vom Defaultwert abweichen soll, alle anderen Parameter "links" von ihm ebenfalls übergeben muss, selbst wenn diese ihre Defaultwerte behalten sollen. Das "const" ganz am Ende der Funktionsdefinition kennen wir ja bereits: Es besagt, dass der QString, auf den die Funktion angewendet wird, selber nicht verändert wird. Der zurückgegebene QString ist also ein neu erzeugter QString.

double a: Der Wert, der umgewandelt werden soll.

int fieldWidth: Der Wert gibt an, wie viele Stellen mit dem Parameter fillChar aufgefüllt werden. (Da es sich um eine überladene Funktion handelt, ist der Parameter nicht an dieser Stelle in der Doku erklärt sondern bei der arg() Funktion, wo er zum ersten Mal auftritt.)

char format: Gibt an, in welcher Schreibweise die Zahl umgewandelt werden soll, also z.B. mit Exponenten.

int precision: Gibt an, wie viele Stellen nach dem Komma dargestellt werden sollen.

const QChar &: Gibt das Zeichen an, welches zum Auffüllen verwendet wird, wenn fieldWidth ungleich Null ist.

Wir wollen Format "f" (floating point) verwenden mit 4 Nachkommastellen. Unser Aufruf ist also arg(a+b,0,'f',4). Damit ist unser Code wie folgt:

double a, b;
a = (InputA -> text()).toDouble();
b = (InputB -> text()).toDouble();
InputC -> setText(QString("%1").arg(a+b,0,'f',4));

%1 ist ein Platzhalter, welcher durch die arg Funktion ersetzt wird. Auch diese Erklärung findet man weiter oben in der Doku, wo sie zum ersten Mal benutzt wird. Es lohnt sich also bei Funktionen, die mehrfach vorkommen, auch die Dokumentation von Versionen anzuschauen, die man eigentlich nicht braucht. Was wir nicht vergessen dürfen ist das Einbinden der QString library in der die Funktion enthalten ist. Das Einbinden erfolgt hierbei mit #include <QString>

Die Datei Taschenrechner.cpp sieht damit so aus:

//--- Taschenrechner.cpp - start ---

#include "Taschenrechner.h"
#include <QString>

Taschenrechner::Taschenrechner(QMainWindow *parent) : QMainWindow(parent){	
	setupUi(this);
	InputA -> setText("0");
	InputB -> setText("0");

	connect(Calculate, SIGNAL (clicked()), this, SLOT(addAB()));
}

Taschenrechner::~Taschenrechner(){
}

void Taschenrechner::addAB(){
	double a, b;
	a = (InputA -> text()).toDouble();
	b = (InputB -> text()).toDouble();
	ResultC -> setText(QString("%1").arg(a+b,0,'f',4));
}

//--- Taschenrechner.cpp - end ---

Nach dem erneuten Übersetzen ist der Taschenrechner fertig zum Addieren. Man könnte jetzt sehr einfach eine Funktion subAB() und einen zusätzlichen Button implementieren, um die Subtraktion einzuführen. Hier soll jedoch einen Schritt weiter gegangen werden: Das Ganze soll übersichtlich in verschiedenen Quellcodedateien implementiert werden.