Login
Newsletter
Werbung

So, 5. März 2006, 00:00

Entwicklung von Applikationen in Qt 4.0

moc

Qt besitzt ein reiches Introspektionssystem. Jede Klasse, die QObject erweitert, kann man nach deren Namen, Liste von Signalen, Slots und Eigenschaften fragen. C++ besitzt keine Introspektionsmechanismen, Qt basiert deshalb auf dem Tool moc (Meta Object Compiler). Dies ist ein Tool, das die Quellen unserer Klasse liest und eine zusätzliche C++-Quelldatei generiert. Diese Datei enthält eine Implementierung der Klasse QMetaObject, die Informationen über unsere Klasse zurückgibt.

qmake fügt in Makefiles Regeln zur Ausführung von moc und Kompilierung der generierten Quellen hinzu, es erfolgt also ohne einen Einsatz des Programmierers. Eine detailliertere Beschreibung befindet sich im Kapitel Meta-Objekte.

designer

Qt Designer ist eine große Applikation, die zum Entwerfen von Benutzeroberflächen dient. Sie ermöglicht, die Benutzeroberfläche zusammenzustellen, indem wir mit der Maus Schaltflächen, Leisten, Textfelder usw. auf ein Formular ziehen. GUI-Elemente kann man mit Layouts verbinden, so dass das Formular nach einer Änderung von Größe oder oder Schriftart immer noch gut aussieht. Designer speichert das entworfene Formular in einer XML-Datei mit der Erweiterung .ui.

uic

uic ist eine Abkürzung von User Interface Compiler. Dies ist ein Programm, das eine .ui-Datei liest und eine C++-Datei generiert, die die Implementierung unseres Formulars enthält. Ähnlich wie im Falle vom moc werden die Regeln, die uic betreffen, im Makefile durch qmake automatisch hinzugefügt.

Die Klasse QObject

In diesem Kapitel beschreiben wir die Klasse QObject, die das Schlüsselelement vieler Mechanismen in Qt ist, darunter die Verwaltung des Speichers, der Signale und Slots sowie der Introspektion.

Eltern und Kinder

Instanzen von QObject organisiert man üblicherweise in einen Baum. Jedes QObject besitzt also ein Elternobjekt und eine Liste von Kindern. Das Entfernen des Elternobjektes (mit Hilfe von delete) hat auch das Entfernen aller seiner Kinder zur Folge. Ein Kind kann man auch manuell entfernen, dann wird es aus der Liste der Kinder seines Elternobjektes automatisch entfernt.

Der Konstruktor der Klasse QObject nimmt als Parameter den Zeiger auf das Elternobjekt an. Der Standardwert dieses Parameters ist 0, was bedeutet, dass das Objekt kein Elternobjekt hat. Den Objektbaum erstellen wir also wie folgt:

QObject *parent = new QObject();
QObject *child1 = new QObject(parent);
QObject *child2 = new QObject(parent);

Nach dem Schreiben des obigen Codes müssen wir uns um eine Deallokation von child1- und child2-Objekten nicht mehr kümmern. Die meisten Probleme, die die Freigabe des Speichers in Qt betreffen, löst man eben auf diese Weise. Das Elternobjekt wird durch die Methode QObject::parent() zurückgegeben. Das Elternobjekt kann man auch mit Hilfe von QObject::setParent() ändern. Kinder werden durch die Funktion QObject::findChild() zurückgegeben.

Meta-Objekte

Jedes Objekt, das QObject erweitert, besitzt ein Meta-Objekt der Klasse QMetaObject. Ein Meta-Objekt dient zur Rückgabe von nützlichen Informationen zum Thema unseres Objektes, wie z.B. den Namen der Klasse und die Liste von Signalen, Slots und Eigenschaften. Alle Instanzen einer Klasse geben dasselbe Meta-Objekt zurück, deshalb wächst die Speichermenge für Meta-Objekte nicht mit der Anzahl von Instanzen, sondern mit der Anzahl von Klassen. Ein Meta-Objekt wird durch die Methode QObject::metaObject() zurückgegeben.

Es stellt sich die Frage, woher kennt das Meta-Objekt den Namen der Klasse und die darin deklarierten Signale und Slots? Listing 1 zeigt eine Beispielklasse, die QObject erweitert. Die Schlüsselrolle spielt hier das Makro Q_OBJECT. Das Makro Q_OBJECT muss in jeder Deklaration jeder Klasse vorkommen, die QObject erweitert. Das Makro deklariert einige zusätzliche private Methoden.

Die Implementation dieser Methoden wird durch moc automatisch generiert und mit der Applikation gelinkt. moc liest eine Header-Datei - zum Beispiel datei.h - und schreibt die Implementierung in eine Datei mit demselben Namen, aber mit dem Präfix moc_, also moc_datei.cpp. moc hat also Zugriff auf alle Informationen über unsere Klasse und ist in der Lage, ein geeignetes Meta-Objekt in der generierten Datei anzulegen.

Signale und Slots

Listing 1. employee.h: Deklaration einer Klasse mit einem Signal und einem Slot

#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include <QtCore/QObject>
class Employee : public QObject
{
 Q_OBJECT
public:
 Employee(QObject *parent = 0);
 int salary() const;
public slots:
 void setSalary(int salary);
signals:
 void salaryChanged(int salary);
private:
 int m_salary;
};
#endif // EMPLOYEE_H

Jede Klasse, die QObject erweitert, kann eine Sammlung von Signalen und Slots besitzen. Signale werden an Slots angebunden und somit wird die Art des Kommunikationsweges im Programm definiert. Zum Beispiel besitzt die Klasse QPushButton das Signal clicked(), das gesendet wird, wenn der Benutzer die Schaltfläche drückt. Dieses Signal kann man z.B. an den Slot close() des Formulars anschließen, wodurch das Klicken auf die Schaltfläche das Formular schließt.

Ein einzelnes Signal kann an eine unbegrenzte Anzahl von Slots angeschlossen werden. Ähnlich können viele Signale an ein Slot angeschlossen werden. Signale und Slots werden beim Schreiben einer Klasse definiert, aber Verbindungen zwischen ihnen kann man während der Arbeit der Applikation dynamisch anlegen und löschen. Die Entwicklung von Applikationen in Qt beruht also auf dem Schreiben von entsprechenden Klassen und deren Ausstattung mit Signalen und Slots.

Kommentare (Insgesamt: 2 || Alle anzeigen )
Pro-Linux
Pro-Linux @Facebook
Neue Nachrichten
Werbung