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

Newsletter abonnieren

Lies uns auf...

Folge LinuxCommunity auf Twitter

Top-Beiträge

„Klickbunt auf dem Server? Warum nicht, wenn's hilft!"
(230 Punkte bei 9 Stimmen)
Wheezy + Kernel 3.9.2 + LXDE
(185 Punkte bei 5 Stimmen)
KDE 4.10.2, Gnome 3.6 und mehr
(143 Punkte bei 5 Stimmen)
Famiientreffen, das Neunzehnte
(121 Punkte bei 4 Stimmen)
Google schmeißt Jabber raus ...
(108 Punkte bei 5 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

Das große Ganze

24 dieser Tuerchen-Objekte wollen nun erschaffen und angeordnet werden – am besten in einem Objekt einer neuen Klasse Adventskalender, die das Hauptfenster stellt. Auch diese einfache Klasse, die lediglich einen Konstruktor besitzt, leiten wir von QWidget ab und schreiben ihr API in eine Datei namens adventskalender.h (Listing 1).

Listing 1

Adventskalender-API

adventskalender.h
#include <qwidget.h>
 class Adventskalender : public QWidget
 {
 public:
   Adventskalender( QWidget *elternwidget = 0,
       const char *name = "adventskalender" );
 };

adventskalender.cpp besteht aus gar nicht besonders viel Programmierung, sondern vor allem aus Festlegungen: Welche Bildchen sollen sich hinter den einzelnen Türchen verstecken, …

#include "1.xpm" // enthaelt bild_1[…]
 #include "24.xpm" // bild_24

für welchen Tag ist welcher Türcheninhalt gedacht, ….

static const char  bilder[24] = {
   bild_1, […], bild_24 };

… und an welchen x-y-Koordinaten soll das für einen bestimmten Tag gedachte Türchen stehen? (Die erste Spalte der ersten Zeile trägt die Koordinate 0,0.)

struct pos{
   int x;
   int y;
 } position[24] = {
   {1, 0}, // Position fuer Tuerchen Nr. 1[…]
   {2, 2}  // Nr. 24
 };

Im Adventskalender-Konstruktor legen wir zunächst ein unsichtbares sechsspaltiges und vierzeiliges Gitter fest, in dem die einzelnen Türchen "einrasten" sollen:

Adventskalender::Adventskalender( QWidget *elternwidget, const char *name )
                : QWidget( elternwidget, name )
 {
   QGridLayout * gitterraster = new QGridLayout( this, 6, 4,
                                    6, 4, "gitterraster" );

Bei den letzten drei Argumenten des QGridLayout-Konstruktors handelt es sich um die Randbreite (6), den Platz zwischen den Zellen (4 Pixel) und die Widget-ID des gitterraster-Zeigers. 24 Türchen erzeugen wir nun in einer for-Schleife, deren Körper innerhalb der geschweiften Klammern erst mit der Zählervariablen i gleich 1 bis hin zur 24 durchlaufen wird (i++ bedeutet, dass der Inhalt von i am Ende jeden Schleifendurchlaufs um eins erhöht wird):

for ( int i = 1; i <= 24; i++ ){
     QString name( "tuerchen" );
     name += QString::number(i);

Damit jedes Tuerchen-Objekt eine eigene ID bekommt, setzen wir sie in der Variablen name zusammen: Beim Türchen, das im ersten Schleifendurchlauf entsteht, lautet sie tuerchen1, beim letzten Durchlauf lautet name auf tuerchen24. name += Wert ist dabei eine Kurzform für name = name + Wert.

Nachdem wir die Tuerchen-API am Anfang der Datei mit #include "tuerchen.h" innerhalb der Adventskalender-Implementierung bekannt gemacht haben, können wir den public deklarierten Tuerchen-Konstruktor nun mit den Argumenten Eltern-Widget, Hintergrundbildchen, Aufschrift und ID aufrufen:

Tuerchen * tuer = new Tuerchen( this, new QPixmap( bilder[i-1] ), i, (const char *) name );

Mit bilder[i-1] holen wir uns dabei das an i-ter Stelle abgelegte XPM aus dem bilder-Array – da die Zählung bei Array-Elementen jedoch bei 0 beginnt, müssen wir als Index i-1 angeben. Indem wir es dem QPixmap-Konstruktor als Argument übergeben, erhalten wir ein passendes Pixmap-Objekt.

Zuletzt bauen wir das neue Tuerchen an passender Stelle ins Layout-Raster ein:

gitterraster->addWidget( tuer, position[i-1].x,
                                    position[i-1].y );
   }

Als Positionsangabe dient jeweils der x- und der y-Wert aus dem position-Element mit dem Index i-1. Tuerchen Nr. 24 wird damit an der Stelle (2,2) im Raster eingebaut.

Das gesamte Adventskalender-Widget färben wir jetzt (wie den Tuerchen-Pushbutton) grün ein und teilen dem Qt-Layout-Management außerdem mit, dass es eine feste, unveränderliche Größe haben soll. Diese berechnen wir jedoch nicht, sondern sagen mit sizeHint() einfach: "Nimm die Größe, bei der alle Teil-Widgets ideal platziert sind."

setBackgroundColor( QColor( 0, 155, 0 ) );
   setFixedSize( sizeHint() );
 }

Finale

Alle Widgets sind da, fehlt nur noch das Applikationsobjekt selbst. In der (allen C/C++-Programmen eigenen) Hauptfunktion main() (Listing 2) übergeben wir eventuelle Kommandozeilen-Optionen und Argumente (in unserem Fall prophylaktisch) an die eigentliche Applikation (argv enthält diese, argc ihre Anzahl). Das neue Adventskalender-Objekt wird in Zeile 8 zum Hauptfenster der Applikation, auf die app zeigt. Zeile 9 sorgt dafür, dass es auch auf dem Bildschirm erscheint, während Zeile 10 die sogenannte Anwendungsschleife startet: Das Adventskalender-Objekt beginnt zu leben. Sobald es geschlossen wird, bekommen wir von exec() einen Rückgabewert, und das Programm beendet sich.

Listing 2

Hauptroutine

advcal.cpp
1 #include <qapplication.h>
  2 #include "adventskalender.h"
  3
  4 int main( int argc, char  argv )
  5 {
  6   QApplication * app = new QApplication( argc, argv );
  7   Adventskalender * advcal = new Adventskalender();
  8   app->setMainWidget( advcal );
  9   advcal->show();
 10   return app->exec();
 11 }

Der Code ist geschrieben (und auf CD komplett nachzulesen) – wie wird daraus jetzt ein ausführbares Programm? Hiermit schlägt tmakes (oder qmakes) große Stunde: Aus einer einfachen Projektdatei, die alle selbstgeschriebenen Header-Dateien unter HEADERS, alle Implementierungsfiles unter SOURCES und den Namen der zu generierenden ausführbaren Datei unter TARGET angibt (Listing 3), wird mit

tmake -o Makefile advcal.pro

ein Makefile. Die CONFIG-Angaben release, qt und warn_on bedeuten, dass wir eine optimalisierte Qt-Applikation erstellen wollen, bei deren Übersetzung der Compiler mehr Warnungen ausgeben soll als üblich. Dass es sich beim Ergebnis um eine Anwendung (und nicht um eine Bibliothek) handelt, legt die TEMPLATE-Variable fest.

Listing 3

Projektdatei

advcal.pro
TEMPLATE = app
 CONFIG   = qt warn_on release
 HEADERS  = adventskalender.h \
            tuerchen.h
 SOURCES  = advcal.cpp \
            adventskalender.cpp \
            tuerchen.cpp
 TARGET   = advcal

Ein make sorgt dann hoffentlich für fehlerfreies Durchkompilieren – und ein ausführbares Binary namens advcal.

Glossar

GUI

"Graphical User Interface" – grafische Benutzerschnittstelle, der für Anwender/innen sichtbare Teil einer grafischen Applikation.

Compiler

Programm, das aus menschenlesbarem Quellcode ein maschinenlesbares ausführbares Binary macht.

Interpreter

Programm, das in einer Skript-Sprache geschriebenen Quellcode interpretiert und sofort ausführt.

Xlib

Die grundlegende Bibliothek, die alle zur Entwicklung einer X-Applikation nötigen (Low-Level-)Funktionen enthält.

basename

Dieses Kommando schneidet von einem Dateinamen, den es als erstes Argument bekommt, die Pfadangabe und ggf. die als zweites Argument angegebene Dateinamensendung ab. Aus tuer.gif in der Variablen bild wird so tuer., und da das basename-Kommando in `Backticks` eingeschlossen wurde, fügt die Shell dessen Ergebnis an deren Stelle ein. So wird letztlich folgendes Kommando ausgeführt:

static

Globale (also außerhalb einer Klasse oder Funktion deklarierte) statische Variablen sind außerhalb ihrer Datei (bzw. der, in die sie mit #include eingelesen wurden) unbekannt.

//

C++-Kommentarzeichen. Alles, was hinter ihm auf der Zeile steht, ignoriert der Compiler.

aufgedrückt

Operator ->, der die darauffolgende Funktion auf das Objekt anwendet, auf das ein Zeiger zeigt. Arbeitet man hingegen mit Objekten, die direkt in Variablen gespeichert sind, so heißt der entsprechende Operator . (Punkt).

Einem Freund empfehlen    Druckansicht Bookmark and Share
Kommentare

Hits
Wertung: 192 Punkte (12 Stimmen)

Schlecht Gut

Infos zur Publikation

Infos zur Publikation

title_2013_06

Aktuelle Ausgabe kaufen:

Heft bestellen 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

Emacs als Psychologe
Emacs als Psychologe
Tim Schürmann, 21.05.2013 11:49, 0 Kommentare

Wer beim Schreiben in Emacs nicht mehr weiter weiß oder schier an einer Programmieraufgabe verzweifelt, der kann den eingebauten Psychologen um Rat fragen.

1966 entwickelte der Infor...

Aktuelle Fragen

Kontakt via QR code hinzufügen
Herman Sproesser, 17.05.2013 17:46, 3 Antworten
Hi hab in der aktuellen ausgabe 06.2013 den artikel über QR Codes gelesen. Ich hab nartürlich...
Dateimanager Dolphin, wo legt er die Datei Kommentare ab?
Uwe Heine, 16.05.2013 15:19, 1 Antworten
Suse Linux 12.1 - KDE 4.7.2 / Dolphin 1.7. Ich habe bei vielen Dateien über Dolphin Kommentare...
wie baut man Kernel Module so, dass sie mit jedem Kernel laden?
GoaSkin , 22.04.2013 10:22, 1 Antworten
Hallo, baut man anhand eines Kernel-Sources Module, nutzt Linux im Normalfall eine strikte V...
Problem beim Installieren von SuSe 12.3
Georg Prokert, 14.04.2013 00:04, 16 Antworten
Hallo, auf meinem neuem Laptop (Acer Aspire V3-771, Intel Core i5-3230 M, Intel HD Graphics 4...
lvm wieder loswerden
Peter Dibbern, 11.04.2013 16:28, 4 Antworten
Ich habe sämtliche alten Kisten ausgeschlachtet und aus der Teilen einen Rechner zusammengeschrau...