Home / LinuxUser / 2001 / 12 / Adventskalender mit C++ und Qt

Newsletter abonnieren

Lies uns auf...

Folge LinuxCommunity auf Twitter

Top-Beiträge

Eingedost
(161 Punkte bei 4 Stimmen)
Aufteiler
(161 Punkte bei 4 Stimmen)

Heftarchiv

LinuxUser Heftarchiv

EasyLinux Heftarchiv

Ubuntu User Heftarchiv

Ubuntu User Heftarchiv

Partner-Links:

Das B2B Portal www.Linx.de informiert über Produkte und Dienstleistungen.

Vorfreude, schönste Freude

Adventskalender mit C++ und Qt

Bekanntmachung

Damit andere Objekte, etwa der Adventskalender selbst, wissen, wie sie Tuerchen erzeugen (und was sie sonst noch damit anstellen können), müssen sie über die Schnittstellen (API, "Application Programmers' Interface") der Tuerchen-Klasse aufgeklärt werden. Diese schreibt man in eine Header-Datei, die sich mit der #include-Direktive leicht dort einlesen lässt, wo sie gebraucht wird. Darin steht, …

#include <qwidget.h>
 class Tuerchen : public QWidget{

…, dass es sich bei Tuerchen um eine von QWidget abgeleitete Klasse handelt, die

public:
   Tuerchen( QWidget*, QPixmap*, const int, const char * );

zur allgemeinen (also öffentlichen, public) Verwendung einen Konstruktor anbietet, der vier Argumente der angegebenen Datentypen verlangt. Nicht für andere Objekte zugänglich sind hingegen die "Ablagen", in denen Tuerchen-Objekte ihre eigenen Daten aufbewahren:

private:
   int aufschrift; // Tag
   QLabel* bild; // Inhalt des Tuerchens
   QPushButton* tuer; // die "Deckplatte"
 };

eine Integer-Variable, die den Tag enthält, für den das Türchen gedacht ist, sowie Zeiger auf das Label mit dem "geheimen" Bildchen und die am entsprechenden Tag "abzunehmende" Deckplatte. Um diese darzustellen, bietet sich ein entsprechend formatierter Knopf an, auf den die neugierigen User klicken sollen – also ein Pushbutton. Die gesamte, mit dem Stichwort class beginnende Klassen-Deklaration ist eine einzige C++-Anweisung, weshalb am Ende das Semikolon nicht fehlen darf.

Doch bislang kennt noch niemand die Klassen QLabel und QPushButton. #include-Anweisungen müssten her. Da Zeiger jedoch nur auf Speicherstellen weisen, die ein entsprechendes Objekt enthalten, brauchen wir an dieser Stelle noch nicht den Ballast der gesamten API für diese Klassen mitschleppen. Mit

class QLabel;
 class QPushButton;

behaupten wir einfach nur vor der Tuerchen-Deklaration, dass diese Klassen bekannt sind. Spätestens, wenn die Klassenvariablen mit Anfangswerten belegt, initialisiert, werden (eine Aufgabe, die dem Konstruktor zufällt) und damit tatsächlich ein Objekt dieser Klasse gespeichert wird, brauchen wir die jeweilige Klassen-API jedoch. Deshalb gehört ein

#include <qlabel.h>
 #include <qpushbutton.h>

an den Anfang der Implementationsdatei tuerchen.cpp. Die API der meisten Qt-Klassen ist in einem Headerfile gleichen Namens (jedoch kleingeschrieben) verstaut, bei den Ausnahmen findet man den passenden Dateinamen am Anfang der jeweiligen Klassendokumentation.

Den Namen der Header-Datei der Tuerchen-Klasse haben wir mit tuerchen.h selbst festgelegt – doch da es sich um eine eigene API handelt, die im selben Verzeichnis wie die cpp-Datei liegt, wird sie beim Einfügen nicht in spitze Klammern, sondern in doppelte Anführungszeichen gesetzt:

#include "tuerchen.h"

Geburtshelfer

Innerhalb der geschweiften Klammern des Tuerchen-Konstruktors belegen wir jetzt die Klassenvariable aufschrift mit dem ganzzahligen Wert aus dem Parameter tag:

aufschrift = tag;

Damit bild, der Zeiger auf das Label mit dem Hintergrundbildchen, tatsächlich auf etwas zeigt, rufen wir mit dem Schlüsselwort new ein neues QLabel-Objekt ins Leben. Dessen Konstruktor ist zufrieden, wenn man ihm das Eltern-Widget als Argument übergibt. Da es ein Kind des jeweiligen Tuerchen-Objekts sein soll, reicht hier das Keyword this:

bild = new QLabel( this );

Das neue, noch leere Label-Objekt bekommt mit der QLabel-Funktion setPixmap() die im Konstruktor-Argument bildchen enthaltene xpm-Grafik aufgedrückt, …

bild->setPixmap( *bildchen );
  bild->setAlignment( Qt::AlignCenter );

…, die wir eine Zeile später zentrieren. Da AlignCenter nichts ist, was QWidget und damit Tuerchen geerbt haben, müssen wir davor den doppelten Doppelpunkt setzen, vor dem wiederum steht, in welcher Klasse (genauer in welchem Namensraum) es definiert ist – in diesem Fall ganz global im Namensraum Qt.

Nicht alle XPMs sind genau quadratisch, weshalb um manche ein Rand in der Standardfarbe des Labels, grau, verbliebe. Das sieht nicht schön aus, und so färben wir das komplette Label mit der Hintergrundfarbe der Pixmaps ein. Bei unseren Beispielbildchen ist das weiß, das netterweise als Qt::white vordefiniert ist.

bild->setPalette( Qt::white );

Genaugenommen sorgen wir mit setPalette() dafür, dass das Label in einer Farbenpalette auf der Basis von Weiß eingefärbt wird. Richtig bemerkbar macht sich dieses Detail bei 3D-Effekten weniger "flacher" Widgets wie dem QPushButton.

Wer hat nicht schon bei Adventskalendern aus Papier versucht, vorzeitig hinter das Geheimnis zu kommen? Selbst wenn sich die Türchen nicht vorzeitig öffnen lassen, kann ein verräterisches Flimmern beim Aufruf (und grafischen Aufbau) des Programms mehr als gewünscht verraten. Daher verstecken wir das bild-Objekt vorsichtshalber mit bild->hide();.

Das Pushbutton-Türchen verlangt ein wenig Vorarbeit. Zwar lesen wir mit #include "tuer.xpm" die in der Variablen bild_tuer abgelegte XPM-Beschreibung des Frontbildchens ein, doch darin ist noch keine Tageszahl integriert. Mit

QPixmap tuerfuellung( bild_tuer );

machen wir aus der Beschreibung erst einmal ein richtiges Pixmap-Objekt (keinen Zeiger!) namens tuerfuellung, das wir mit

QPainter leinwand( &tuerfuellung );

auf eine virtuelle Leinwand kleben. Jetzt holen wir einen weißen Stift für diese leinwand

leinwand.setPen( Qt::white );

und schreiben in der linken, oberen Ecke (Qt::AlignTop) eines auf dem QPainter links oben (bei den Koordinaten 0,0) beginnenden Rechtecks von 64 Pixeln Breite und eben dieser Höhe den Text, der in der Variablen aufschrift gespeichert ist:

leinwand.drawText( 0, 0, 64, 64, Qt::AlignTop, QString::number( aufschrift ) );

aufschrift ist aber eine ganzzahlige Zahl und kein Text. Den machen wir aus ihr mit Hilfe der QString-Funktion number(). Wir räumen die Staffelei weg (leinwand.end();) und erzeugen den Button mit der veränderten Pixmap, auf den unser Zeiger tuer weisen soll:

tuer = new QPushButton( this );
  tuer->setPixmap( tuerfuellung );

Auch das Türfüllungsbild misst nicht ganz 64x64 Pixel, weshalb es sich anbietet, die Farbpalette des hinter tuer versteckten Objekts entsprechend anzupassen. Mit Tools wie xv oder display erfährt man den RGB-Wert der entsprechenden Hintergrundfarbe, bei tuer.xpm auf der CD ist es ein Rotanteil von 0, ein Grünanteil von 155 und ein Blauanteil von 0. Da setPalette() auch QColor-Objekte als Argument entgegennimmt, machen wir aus dem RGB-Wert zunächst ein solches:

tuer->setPalette( QColor( 0, 155, 0 ) );

Damit das komplette Tuerchen-Objekt nicht über die Größe der darin enthaltenen Bildchen hinauswächst, legen wir noch eine feste Größe fest:

setFixedSize( 64, 64 );
Tip a friend    Druckansicht Bookmark and Share
Kommentare

Hits
Wertung: 200 Punkte (22 Stimmen)

Schlecht Gut

Infos zur Publikation

Infos zur Publikation

LinuxUser 05/2014

Aktuelle Ausgabe kaufen:

Heft als PDF kaufen

LinuxUser erscheint monatlich und kostet in der Nomedia-Ausgabe EUR 5,95 und mit DVD EUR 8,50. Weitere Informationen zum Heft finden Sie auf der LinuxUser-Homepage.

Im LinuxUser-Probeabo erhalten Sie drei Ausgaben für 3 Euro. Das Jahresabo (ab EUR 60,60) können Sie im Medialinx-Shop bestellen.

Tipp der Woche

Bilder vergleichen mit diffimg
Bilder vergleichen mit diffimg
Tim Schürmann, 01.04.2014 12:40, 1 Kommentare

Das kleine Werkzeug diffimg kann zwei (scheinbar) identische Bilder miteinander vergleichen und die Unterschiede optisch hervorheben. Damit lassen sich nicht nur Rätsel a la „Orignial und Fäls...

Aktuelle Fragen

programm suche
Hans-Joachim Köpke, 13.04.2014 10:43, 8 Antworten
suche noch programme die zu windows gibt, die auch unter linux laufen bzw sich ähneln sozusagen a...
Funknetz (Web-Stick)
Hans-Joachim Köpke, 04.04.2014 07:31, 2 Antworten
Bei Windows7 brauche ich den Stick nur ins USB-Fach schieben dann erkennt Windows7 Automatisch, a...
Ubuntu 13.10 überschreibt immer Windows 8 Bootmanager
Thomas Weiss, 15.03.2014 19:20, 8 Antworten
Hallo Leute, ich hoffe das ich richtig bin. Ich habe einen Dell Insipron 660 Ich möchte gerne Ub...
USB-PTP-Class Kamera wird nicht erkannt (Windows-only)
Wimpy *, 14.03.2014 13:04, 15 Antworten
ich habe meiner Frau eine Digitalkamera, AGFA Optima 103, gekauft und wir sind sehr zufrieden dam...
Treiber
Michael Kristahn, 12.03.2014 08:28, 5 Antworten
Habe mir ein Scanner gebraucht gekauft von Canon CanoScan LiDE 70 kein Treiber wie bekomme ich de...