Aus Linux-Magazin 05/2005

Vorschau auf die neue Qt-Version 4

Mit dem C++-Toolkit Qt der norwegischen Firma Trolltech erstellen Programmierer Crossplattform-Anwendungen für Linux, Windows oder Mac OS. Auch der KDE-Desktop basiert auf Qt. Dieser Artikel gibt einen Ausblick auf die kommende Version Qt 4.0 und zeigt, worauf Umsteiger achten müssen.

Benutzer des Qt-Toolkits schwören auf das intuitive API und die umfangreiche Dokumentation. Nicht nur freie Softwareprojekte wie Scribus, auch Firmen wie Mainconcept und Opera Software verwenden das Toolkit. Traditionell nutzt der Hersteller Trolltech die so genannten Major-Releases für eine Umstrukturierung des API.

Daher reicht es nicht, bei der Veröffentlichung einer neuen Version eigene Programme erneut zu kompilieren. Entwickler müssen ihren Code an die neue Schnittstelle anpassen. Trolltech hat aber offensichtlich aus den Problemen beim Umstieg von Qt 1 auf 2 gelernt. Neben einer offenen Preview- und einer ausgiebigen Beta-Phase hat sich das Unternehmen kurzfristig dazu entschieden, die Release der endgültigen Version ins “späte zweite Quartal” zu verlegen. Bisher war stets vom späten ersten Quartal die Rede.

Die Verspätung ist nachvollziehbar: Wer die Snapshots per Rsync[1] oder FTP[2] verfolgt, dem fallen zurzeit noch zahlreiche Fehler auf. Mitgelieferte Programme wie der Qt Designer kompilieren zeitweise gar nicht. Nach dem Erscheinen der zweiten Betaversion Mitte März sollte sich die Codebasis jedoch stabilisiert haben.

Dem Problem, dass Entwickler den gesamten Code, der auf der Qt-3-Bibliothek aufsetzt, überarbeiten müssen, begegnet Trolltech mit einem Konvertierungstool. Außerdem gibt es auf der Website eine detaillierte Einführung in die Technologien der neuen Version sowie Portierungshinweise unter[3] und[4], die sich jeder Entwickler anschauen sollte.

Mit Leichtigkeit</>

Den Ballast, den Qt 3.3 mit sich führt, wirft die neue Bibliothek ab. Denn seit Version 2.0 hat Trolltech sich praktisch von keiner Klasse getrennt. Dadurch erhöhte sich die Größe der monolithischen Bibliothek stetig, aktuell bringt sie stattliche 8,3 MByte auf die Waage. Somit hatte auch Qt 3 im Embedded-Bereich niemals denselben Erfolg wie sein Vorgänger; das im Embedded-Markt sehr verbreitete und beliebte Qtopia verwendet weiterhin Qt 2 Embedded.

Doch die Vorteile der Umstrukturierung bringen auch Nachteile mit sich: Ein Qt-3-Programmierer muss sich mit der neuen Version sehr stark umstellen. Das hat Trolltech erkannt und den Porting Guide erstellt[4]. Die Norweger teilen ihr Toolkit in nunmehr elf Bibliotheken auf, was den Speicherbedarf der Applikationen reduziert.

Programmautoren linken nur noch gegen die für sie relevanten Bibliotheken. Außerdem wandern alle veralteten Qt-Klassen in ein »Qt3Support«-Modul und erhalten ein »3«-Infix. Aus »QCString« wird »Q3CString«, da ihr Ersatz in Qt 4 »QByteArray« ist. Andere Klassen besitzen Kompatibilitätsfunktionen. Beide Portierungshilfen sind optional und lassen sich über ein Makro abschalten.

Im Zeichen der Effizienz

Erstmalig ist es auch möglich, alle Header einer Gruppe auf einmal einzubinden. »#include <QtGui>« zieht alle Header der »QtGui«-Bibliothek ins Programm. Diese Schreibweise, auch Java Case genannt, gilt für alle Klassen-Includes. Somit entspricht der Name eines Include immer dem Namen der entsprechenden Klasse. Die ».h«-Endung entfällt, was nach ISO-C++-Spezifikation Systemheader auszeichnet. Die alte Schreibweise »#include <header.h>« funktioniert jedoch nach wie vor. Ein kleines Manko bilden Klassen wie »QCanvas«, die ins »Qt3Support«-Modul abgeschoben sind, ohne dass für sie ein sinnvoller Ersatz existiert. Trolltech verspricht Nachfolger für die betroffenen Klassen in Qt 4.1 nachzureichen.

Eine wichtige Neuerung ist das Symbol- Hiding für GCC. Es entspricht etwa dem DLL-Export-Feature des Microsoft-C++-Compilers und ist vor allem für Programmierer von Nutzen, die Bibliotheken mit Qt schreiben. Nur Klassen und Funktionen, die zum API zählen, macht der Programmierer mit dem Schlüsselwort »Q_ DECL_EXPORT« nach außen sichtbar. Er stellt das Makro in der Deklaration hinter das »class«-Schlüsselwort beziehungsweise bei einer Funktion vor den Rückgabewert.

Ohne Maus

Dass der Linker dann mit wesentlich weniger Symbolen in den Objekten zu kämpfen hat, macht sich sowohl beim Entwickler als auch beim Endbenutzer durch höhere Geschwindigkeit bemerkbar. Leider funktioniert dieses Feature bei GCC erst mit Version 4.0 oder höher. Einige Linux-Distributoren haben die Funktionalität auf GCC 3.4 zurückportiert, es ist also nicht immer ein Compiler-Upgrade erforderlich.

Um die Entwicklung von Programmen ohne GUI zu erleichtern, gibt es in Qt 4 einige Klassen zusätzlich in einer vereinfachten Version, die unabhängig von grafischen Oberflächen ist. Während in Qt 3 ein boolescher Schalter in der »QApplication«-Klasse dazu diente, einem Programm die Grafik auszutreiben, verwenden Programmierer in Qt 4 einfach die »QCoreApplication«. Eine weitere von der Modultrennung betroffene Klasse ist »QVariant«, die eine kleine Schwester namens »QCoreVariant« hat.

Die »Qt«-Klasse, die grundlegende Definitionen enthielt und von der ursprünglich alle Qt-Klassen erbten, ist nun ein Namensraum. Dank des Vererbungsprinzips durften Entwickler etwa bei Enumeratoren bisher auf das Qt-Präfix verzichten. Das ist in Qt 4 nicht mehr möglich. Wer nicht in seinem gesamten Code das Präfix voranstellen möchte, dem rät die Dokumentation, eine »using namespace Qt;«-Anweisung in den Quelltext einzufügen. Das führt jedoch wieder bei einfachen Namen wie beispielsweise den Definitionen der Qt-Farbpalette zu Mehrdeutigkeiten. Denn »yellow« könnte auch der Name einer Variablen sein, »Qt::yellow« identifiziert hingegen eindeutig die Qt-Farbdefinition. Hier ist also Vorsicht geboten.

Noch schneller

Die Konstruktoren von »QObject«-basierten Klassen nehmen in Qt 4 keinen Namen mehr an. Ihn setzen Entwickler später mittels »setObjectName()«. Die »WFlags«, die auch »QWidgets« als Konstruktorparameter übergeben bekam, sind jetzt in »WindowFlags« und »WidgetAttributes« aufgeteilt. »WindowFlags« sind Hinweise für den Fenstermanager, während »WidgetAttributes« sich direkt an Qt richten.

Einige Programmierer schalten aus Platzgründen die Runtime Type Information (RTTI) aus, die manche Applikationen für dynamisches Casting benötigen. Wer sich aber nicht auf einen »static_ cast« verlassen will, ist unter Qt 3 zu Konstrukten ähnlich dem folgenden gezwungen:

MyWidget *mw;
if (w->inherits("MyWidget"))
   mw = static_cast<MyWidget*>(w);

Das bedeutet einige langsame Stringvergleiche und eine Menge Tipparbeit. Qt 4 löst das Problem zumindest für »QObject«-basierte Klassen mit »qobject_cast«. Es verwendet die Metainformationen des Metaobjekt-Compilers (»moc«), ist typsicher und schneller als der alte Ansatz. Laut Trolltech soll »qobject_cast« sogar schneller sein als die nativen »dynamic_cast«-Implementierungen des GCC. Hinter dem »QPointer«-Container verbirgt sich eine im Laufzeitverhalten verbesserte Version des »QGuardedPtr« aus Qt 3. Er enthält »QObject«-basierte Klassen und setzt sie automatisch auf 0, falls das enthaltene Objekt gelöscht ist.

Tulpen aus Oslo

Auch bei den Containern von Qt hat sich viel getan. Hinter dem Namen Tulip verbergen sich neue Container, die die QTL- und »QCollection«-basierten Container ablösen. »QList« ersetzt »QPtrList« und »QValueList«. »QPtrList<QObject>« in Qt 3 entspricht also »QList<QObject*>« in Qt 4. Den Aufruf »setAutoDelete(true)« haben die Norweger durch die Template-Funktion »qDeleteAll()« ersetzt, die wahlweise entweder eine Liste oder zwei Iteratoren als Parameter übergeben bekommt.

Neben »QList« enthält Tulip die Klassen »QVector«, »QLinkedList«, »QMap« und »QHash« sowie »QQueue« für Lifo- und »QStack« für Fifo-Operationen. Trolltech empfiehlt »QList« bei Listen. Eine »QLinkedList« ist nur dann sinnvoll, wenn die Anzahl der Einfüge-Operationen die der Such-Operationen deutlich übersteigt und das Einfügen in konstanter Zeit geschehen soll. »QVector« eignet sich besonders für Listen, in die das Programm nur am Ende Elemente einfügt. Die Dokumentation mahnt jedoch einen sparsamen Umgang an.

Qt 4 führt erstmalig ein »foreach«-Schlüsselwort ein. Um beispielsweise den Inhalt einer »QStringList« namens »liste« auszugeben, genügen zwei einfache Zeilen Code:

foreach(QString element, liste)
  std::cout << element << std::endl;

Foreach verhält sich dabei wie bei einer For-Schleife. Die Dokumentation weist jedoch darauf hin, dass Qt vor Eintritt in die Schleife eine Kopie des Containers anfertigt. Operationen in der Schleife beeinflussen nicht den Originalcontainer. Zusätzlich gibt es die Schleife »forever()«, die einem »for( ;; )« entspricht.

Ansichtssache

Um Daten grafisch darzustellen, standen unter Qt 3 mehrere Klassen zur Verfügung: »QIconView« für frei verschiebbare Objekte, »QListBox« für einfache Listen, »QListView« zeigte verzweigte und mehrspaltige Listen an und »QTable« stellt Tabellen dar, wie Anwender sie aus Tabellenkalkulationen kennen. Den Inhalt der Listen beschrieben Programmierer der 3er Version durch Items, die aber unter den Ansichten nicht austauschbar waren, da die Klassen neben den Daten auch ihr eigenes Aussehen definierten. Es war in der Vergangenheit nicht einfach, dieselben Daten aus einer Quelle (Model) in unterschiedlichen Ansichten (Views) zu zeigen.

In Qt 4 hält mit Interview eine modifizierte Version des Model View Controller (MVC) Einzug, ein von Smalltalk abgeleiteter Ansatz zur Datendarstellung. Bei Interview sind View und Model in einem Objekt zusammengefasst, das resultierende Konzept nennen die Norweger schlicht Model-View-Architektur und fügen ihm ein neues Objekt hinzu, den so genannten Delegate.

Der Delegate zeichnet für die grafische Darstellung der Modeldaten in der View verantwortlich und versorgt sie bei Bedarf mit einer Editorkomponente. Mit dieser bearbeiten Anwender Daten direkt in der Ansicht (inline). Models erben stets von »QAbstractItemModel«, Views von »QAbstractItemView« und Delegates von »QAbstractDelegate«.

Wer nun befürchtet, jedes Mal sein eigenes Tabellenwidget bauen zu müssen, sollte die Klassen »QTableView«, »QListView« und »QTreeView« unter die Lupe nehmen. Sie entsprechen recht genau den Klassen aus Qt 3 und enthalten dazu eine passende View samt Delegate-Funktionen. Denen übergibt der Programmierer einfach das Model. »QListView« enthält dabei auch die ehemals in »QIconView« implementierte Icon-Ansicht. Auch Models sind vorgefertigt integriert. So stellt zum Beispiel ein »QDirModel« die klassische Verzeichnisansicht dar (Abbildung 1), »QStandardItemModel« erlaubt das Speichern beliebiger Daten in einem Container.

Abbildung 1: Die Klasse »QDirModel« stellt eine komplette Verzeichnisansicht zur Verfügung, die zugleich für eine Baum- und eine Listen-Darstellung arbeitet.

Abbildung 1: Die Klasse »QDirModel« stellt eine komplette Verzeichnisansicht zur Verfügung, die zugleich für eine Baum- und eine Listen-Darstellung arbeitet.

Das neue SQL-Modul stellt insgesamt drei Modelle zur Verfügung, um Datenbankabfragen direkt anzuzeigen: »QSqlQueryModel« definiert die Read-only-Darstellung einer Abfrage. »QSqlTableModel« bildet eine komplette SQL-Tabelle ab, in die Anwender auch schreiben dürfen. »QTableView« ist hierbei die nahe liegende Wahl.

»QSqlRelationalTableModel« geht einen Schritt weiter und erlaubt Tabellen mit Schlüsseln, die andere Tabellen referenzieren. Listing 1 bildet eine Tabelle namens Waren auf eine »QTableView« ab, die aus den Feldern ID, Name und Preis besteht. Die Edit-Strategie »OnFieldChange« sorgt dafür, dass alle Änderungen sofort in der Datenbank landen.

Listing 1:
SQL-Tabellen darstellen

01 QSqlTableModel *model = new QSqlTableModel;
02 model->setTable("Waren");
03 model->setEditStrategy(QSqlTableModel:: OnFieldChange);
04 model->select();
05 model->removeColumn(0); // Feld "ID" nicht anzeigen!
06 model->setHeaderData(0, Qt::Horizontal, QObject::tr("Name"));
07 model->setHeaderData(1, Qt::Horizontal, QObject::tr("Preis"));
08 
09 QTableView *view = new QTableView;
10 view->setModel(model);
11 view->show();
Abbildung 2: Die neuen Textklassen von Scribe vereinfachen das Layout in Textwidgets und ermöglichen gezielte Manipulationen am Textfluss.

Abbildung 2: Die neuen Textklassen von Scribe vereinfachen das Layout in Textwidgets und ermöglichen gezielte Manipulationen am Textfluss.

Eifriger Maler

Für die Grafikfreunde unter den Programmierern hat Trolltech das Painting Framework stark überarbeitet. Qt zeichnet nun, abhängig vom Betriebssystem, auf insgesamt neun APIs. Darunter GDI, GDI+, OpenGL, Postscript, Quick Draw, X11, VNC und Framebuffer. Weitere Backends, etwa für die Cairo Engine von Freedesktop.org, lassen sich flexibel nachrüsten. Es genügt, von der Klasse »QPaintEngine« abzuleiten und die Funktionalität für das neue Ausgabesystem zu implementieren. Die Klasse »QPainter« unterstützt ab Qt 4 Pfade, Alphablending, Antialiasing sowie Gradienten. Geometrie-Grundtypen wie »QPoint« und »QRect« gibt es jetzt auch als Fließkomma-Varianten, um die Genauigkeit zu erhöhen.

Beschränkte sich die Kontrolle über Textdokumente in Text-Widgets bisher auf die Formatierung durch HTML-Tags, so erlaubt die neue Engine Scribe feineren Zugriff auf die Teile eines Dokuments. Statt eines »QString« bildet nun die »QTextDocument«-Klasse die Schnittstelle zu Widgets wie »QTextEdit«, sie enthält neben der internen Struktur des Textes auch einen eingebauten Undo-Redo-Mechanismus.

Herr der Ressourcen

Um ein »QTextDocument« zu verändern, stellt das Scribe-API die Klasse »QTextCursor« zur Verfügung. Sie verhält sich ganz ähnlich wie ein Cursor auf dem Bildschirm; sobald die gewünschte Position erreicht ist, fügt der Entwickler Bilder, Tabellen oder Textfragmente ein, löscht oder manipuliert sie. Listing 2 zeigt ein Codefragment, das die erste Zeile eines Dokuments fett formatiert. Der »movePosition«-Aufruf in Zeile 6 spannt intern eine Auswahl auf, auf die »mergeCharFormat« die neue Zeichenformatierung anwendet.

Listing 2: Text
formatieren

01   QTextEdit *edit = new QTextEdit;
02   QTextDocument *document = edit->document();
03   QTextCursor cursor(document);
04 
05   cursor.movePosition(QTextCursor::Start);
06   cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
07 
08   QTextCharFormat format;
09   format.setFontWeight(QFont::Bold);
10 
11   cursor.mergeCharFormat(format);
12 
13   edit->show();

Die Verwaltung von Ressourcen wie Bildern ist mit Qt 4 sehr einfach: Das »QMimeSource«-Konzept hat Trolltech komplett ersetzt. Auch der Einsatz des »qembed«-Tools ist nicht mehr notwendig. Entwickler binden alle externen Dateien über eine XML-Datei mit der Endung ».qrc« ein. Beim Kompilieren fügt Qt die Dateien dann direkt in das fertige Binary ein. Dadurch erhöht sich die Geschwindigkeit von grafiklastigen Programmen enorm (siehe Abbildung 3). Das mitgelieferte Werkzeug »rcc« zeigt Ressourcen in einem fertigen Binary an. Ein Beispiel für die entsprechenden XML-Dateien sieht so aus:

<!DOCTYPE RCC><RCC version="1.0">
  <qresource>
    <file>images/apple.png</file>
    ...
  </qresource>

Um dieses Feature zu nutzen, schreibt man einen Doppelpunkt vor den entsprechenden Pfad. Das klappt in allen Funktionen, in denen Qt einen Pfad zur Referenzierung von externen Dateien vorsieht. Dann hält die Bibliothek nicht im Dateisystem, sondern in ihren Ressourcen Ausschau.

Das folgende kurze Beispiel demonstriert anschaulich den Einsatz von Ressourcen in einem Rich-Text-Widget:

QString text = "Hallo Welt, dies ist 
eine Uhr: <img src=":/images/clock. 
png" />";
QTextBrowser *browser = new QTextBrowser;
browser->setHtml(text);
browser->show();
Abbildung 3: Dieses komplette Download-Widget ist mit nur 155 Zeilen Code implementiert. Alle Grafiken liegen als Ressourcen direkt im Binary. Das neue Model-View-Konzept vereinfacht die Programmierung.

Abbildung 3: Dieses komplette Download-Widget ist mit nur 155 Zeilen Code implementiert. Alle Grafiken liegen als Ressourcen direkt im Binary. Das neue Model-View-Konzept vereinfacht die Programmierung.

Fadenscheinig

Das Netzwerkmodul von Qt beherrscht mit der neuen Version erstmals Internationale Domainnamen (IDN) und erreicht eine bessere Performance. Außerdem haben die Entwickler den UDP-Support verbessert und einigen Klassen intuitivere Namen gegeben. Diese änderten sich allerdings noch bei Redaktionsschluss oft und werden auf den Mailinglisten kontrovers diskutiert[5].

Die wichtigste Änderung betrifft die »QSocketDevice«-Klasse, die nicht mehr Teil des öffentlichen API ist. An ihre Stelle rücken »QTcpSocket« und »QUdpSocket«, die beide auch blockierend arbeiten. Dabei warten sie auf eine Verbindung, ohne in die Eventschleife zurückzukehren. Das ist sinnvoll, wenn der Programmierer die Socketfunktionen in einen eigenen Thread auslagert, der das GUI sowieso nicht blockiert.

Im Threading-API selbst haben sich entscheidende Änderungen ergeben. Die »QThread«-Klasse erbt nun von »QObject«. Damit wird auch ein alter Wunsch vieler Qt-Programmierer wahr: Signal-Slot-Verbindungen lassen sich nun über Thread-Grenzen hinweg herstellen. Jeder Thread verfügt auf Verlangen über eine eigene Eventloop und darf somit auch einige nicht-GUI-orientierte Klassen wie »QTcpSocket« und »QTimer« verwenden.

»QMutex« hat Trolltech durch »QReadWriteLock« ersetzt, das Lese- und Schreibrechte auf Daten getrennt setzt. In Qt 4 entfällt auch der Compilezeit-Schalter zum Deaktivieren von Threads. Von nun an gibt es Qt nur noch mit aktiviertem Multithreading.

Werkzeuge

Seit geraumer Zeit begleiten der grafische GUI-Editor Designer, die Übersetzungssoftware Linguist und der Dokumentationsbrowser Assistant jede Qt-Release. Während in den aktuellen Qt-4-Snapshots Linguist und Assistant keine fundamentalen Änderungen zeigen, haben die Norweger den Designer von Grund auf neu entwickelt. Nach dem Start erweckt er eher den Eindruck einer Gimp-Mutation, die MDI-Umgebung ist nur noch optional; stattdessen öffnen sich mehrere Fenster.

Designer-Anwender wählen nach dem Erstellen einer neuen Form aus der Widget-Box das passende Widget aus und ziehen es per Drag&Drop in das Formular (siehe Abbildung 4). Der Property Inspector präsentiert die Eigenschaften des aktuellen Widget, der Object Inspector zeigt alle Objekte im Formular.

Das Ziel ist, den Designer in IDEs wie KDevelop und Visual Studio zu integrieren. Daher besitzt er auch keinen eingebauten Editor mehr. Leider ist die Integration in KDevelop bisher nicht abgeschlossen. Auch von dem Konzept der ».ui.h«-Dateien und der Reimplementierung ist der neue Designer abgerückt. Details zu Trolltechs Neuerungen finden sich in dem Kasten “Neues Designer-Konzept”.

Abbildung 4: Der neue Designer erinnert ein bisschen an Gimp und besteht nicht nur äußerlich aus Komponenten.

Abbildung 4: Der neue Designer erinnert ein bisschen an Gimp und besteht nicht nur äußerlich aus Komponenten.

Neues
Designer-Konzept

Nachdem ein neues Widget im Designer entstanden ist, generiert »uic« die Klasse nicht mehr selbst. Das ist ab sofort Sache des Programmierers. Dafür erstellt UIC eine Headerdatei mit Präfix »ui_«, in der sich eine Klasse mit demselben Namen wie das erstellte Widget befindet. Heißt der Dialog also »MyDialog«, nennt sich die Datei »ui_MyDialog.h« (siehe Listing 3a).

Diese stellt die Widgets des Formulars als Memberklassen sowie eine Funktion namens »setupUi()« zur Verfügung. Sie erwartet einen Zeiger auf ein Widget als Argument. Von da ab gibt es drei Wege, auf das Widget zuzugreifen. Wenn es schnell gehen soll, erstellt der Programmierer einfach ein Widget und übergibt einen Zeiger darauf an »setupUi()« (siehe Listing 3b). Diese Variante ist jedoch nur dann praktikabel, wenn das Programm die Membervariablen des Widget nicht weiter benötigt. Denn von »window« aus ist ohne weiteres keine elegante Zugriffsmöglichkeit auf »ui« gegeben.

Es geht auch eleganter

Eine bessere Möglichkeit besteht daher darin, von »QDialog« zu erben und die UI-Klasse als Member des Dialogs zu behalten (Listing 3b, ab Zeile 11). Der Aufruf im Konstruktor lautet dann »ui.setupUi(this)«. Die Membervariable »ui« ermöglicht jederzeit den Zugriff auf die per Designer erstellten Widgets in der eigenen Klasse »MyDialog«.

Wer nicht den Umweg über den Member gehen möchte, setzt multiple Vererbung ein (Listing 3b, ab Zeile 21). Nun wirkt es – bis auf den Aufruf »setupUi(this)« – so, als ob sich die mit Designer erstellten Widgets direkt in der Klasse befänden und als »private« markiert wären. Diese Variante ist in der Praxis am sinnvollsten und nach kurzer Eingewöhnung auch am leichtesten zu handhaben.

Fazit

Trolltech ist im Begriff, Qt 4 als C++-Toolkit zu etablieren, das in vielen Aspekten mit modernen Sprachen wie Java oder C# gleichzieht. Gegenüber ihrer Vorgängerin ist die vierte Auflage durch Abstraktion flexibler geworden, ohne Entwicklern zusätzliche Arbeit aufzubürden. Mit einer sinnvollen Anzahl von Convenience-Klassen bleibt das Toolkit eine gute Wahl, um einfache Probleme schnell zu lösen und das Rad nicht neu erfinden zu müssen.

Zusätzlich versprechen zahlreiche Optimierungen, das Symbol-Hiding und nicht zuletzt die Aufteilung in einzelne Bibliotheken einen Performancegewinn und geringeren Speicherbedarf. Die beim Erscheinen dieses Heftes wahrscheinlich bereits veröffentlichte Beta 2 sollte das Ende der heftigen Änderungen einläuten, denen die Snapshots derzeit noch unterliegen. Wer sich für Qt 4 interessiert und eventuell in Qt 3 Erfahrung hat, sollte mit der Beta erste Experimente wagen, um sich frühzeitig an die Unterschiede zur Vorgängerversion zu gewöhnen. (mwe)

Listing 3a:
»ui_MyDialog.h«

01 namespace Ui {
02 public:
03   QVBoxLayout *vboxLayout;
04   QPushButton *okBtn;
05   QPushButton *cancelBtn;
06   [...]
07   inline void setupUi(QDialog* dialog);
08   inline void retranslateUi(QDialog* dialog);
09 }
10 
11 inline void MyDialog::setupUi(QDialog *dialog) {
12   dialog->resize(QSize(400, 300).expandedTo(dialog->minimumSizeHint()));
13   dialog->setObjectName(QString::fromUtf8("AboutDialog"));
14   vboxLayout = new QVBoxLayout(dialog);
15   vboxLayout->setObjectName(QString::fromUtf8("unnamed"));
16   vboxLayout->setResizeMode(QLayout::Minimum);
17   [...]
18 }
19 
20 inline void MyDialog::retranslateUi(QDialog *dialog) {
21   dialog->setWindowTitle(QApplication::translate("AboutDialog");
22   [...]
23 }

Listing 3b:
Designer-Beispiele

01 // Möglichkeit 1
02 int main(int argc, char *argv[]) {
03     QApplication app(argc, argv);
04     QDialog *window = new QDialog;
05     Ui::MyDialog ui;
06     ui.setupUi(window);
07     window->show();
08     return app.exec();
09 }
10 
11 // Möglichkeit 2
12 #include "ui_MyDialog.h"
13 class MyDialog : public QDialog {
14     Q_OBJECT
15 public:
16     MyDialog(QWidget *parent = 0);
17 private:
18     Ui::MyDialog ui;
19 };
20 
21 // Möglichkeit 3
22 #include "ui_MyDialog.h"
23 class MyDialog : public QDialog, private Ui::MyDialog {
24     Q_OBJECT
25 public:
26     ImageDialog(QWidget *parent = 0);
27 };

Infos

[1] Trolltechs Rsync-Repository: [rsync://rsync.trolltech.com]

[2] Qt-Snapshots: [ftp://ftp.trolltech.com/qt/snapshots/]

[3] Qt-4-Infoseite: [http://www.trolltech.com/products/qt/qt4info.html]

[4] Portierungshinweise: [http://doc.trolltech.com/4.0/porting4.html]

[5] Qt-4-Mailingliste: [http://lists.trolltech.com/qt4-preview-feedback/]

LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben