Entwicklung von Applikationen in Qt 4.0
#include <QtGui/QApplication> #include <QtGui/QPushButton> #include <QtGui/QLabel> #include <QtGui/QMouseEvent> #include <QtGui/QPalette> #include <QtGui/QVBoxLayout> class HelloWorldLabel : public QLabel { Q_OBJECT public: HelloWorldLabel(const QString &text, QWidget *parent = 0); protected: virtual void mousePressEvent(QMouseEvent *event); }; HelloWorldLabel::HelloWorldLabel(const QString &text, QWidget *parent) : QLabel(text, parent) {} void HelloWorldLabel::mousePressEvent(QMouseEvent *event) { event->accept(); QPalette palette = this->palette(); QPoint pos = event->pos(); int r = 255 * pos.x() / width(); int g = 255 * pos.y() / height(); int b = 255; palette.setColor(QPalette::Foreground, QColor(r, g, b)); setPalette(palette); update(); } int main(int argc, char *argv[]) { QApplication app(argc, argv); QWidget window; QVBoxLayout layout(&window); HelloWorldLabel label("Hello World!", &window); label.setAlignment(Qt::AlignCenter); label.setFont(QFont("Arial", 20, QFont::Bold)); layout.addWidget(&label); QPushButton button("Close", &window); QObject::connect(&button, SIGNAL(clicked()), &window, SLOT(close())); layout.addWidget(&button); window.show(); return app.exec(); } #include "main.moc"
Verfeinern wir das Programm Hello World!, so dass ein Klick auf das Label dessen Farbe ändert. In Listing 7 sehen wir die Klasse HelloWorldWidget
, die QLabel
erweitert. Die Klasse überlädt mousePressEvent()
. Innerhalb dieser Funktion wählen wir eine neue Farbe anhand der Lage der Maus und aktualisieren die Farbpalette. Am Ende rufen wir QWidget::update()
auf. Diese Funktion fügt zur Ereigniswarteschlange ein an sich adressiertes QPaintEvent
hinzu, infolgedessen wird das ganze Widget vom Anfang an im nächsten Zyklus der Ereignisschleife gezeichnet.
Bemerkenswert ist auch der Aufruf event->accept()
. Er signalisiert, dass das Ereignis behandelt wurde. Wenn accept()
ausgelassen wäre, würde QMouseEvent
dem Elternobjekt des Objektes, also dem Hauptfenster, übergeben. Die Standardimplementierung von QWidget::mousePressEvent()
ist leer, es würde deshalb nichts passieren. Beim Schreiben einer größeren Applikation passiert es manchmal, dass bei Auslassen von accept()
dasselbe Ereignis mehrfach behandelt wird.
Die main-Funktion hat sich nur so geändert, dass wir statt QLabel
ein Objekt vom Typ QHelloWorldLabel
anlegen. Interessant ist die letzte Zeile, in der wir die Datei main.moc einlesen. Wenn qmake
nach QObjects
sucht, beschränkt sich es nicht nur auf Header-Dateien. Es scannt auch Dateien in der Variable SOURCES
. Somit können wir lokale QObject
erweiterende Klassen innerhalb von cpp-Dateien deklarieren. Wenn moc
das Meta-Objekt für eine in der cpp-Datei deklarierte Klasse generiert, wird das Ergebnis in eine Datei mit demselben Namen und der Erweiterung moc geschrieben. Wenn wir sie einlesen, fügen wir die Implementation des Meta-Objektes zu unserem Code hinzu.
Zeichnen
Wenn ein Widget zum ersten Mal auftaucht oder irgendwelche Ereignisse auf dem Desktop bewirken, dass es völlig oder teilweise sichtbar ist, veranlasst QApplication
das Zeichnen des entsprechenden Teils des Widgets, indem ihm das Ereignis QPaintEvent
gesendet wird. Diese Klasse hat die Methode rect()
, die ein Objekt vom Typ QRect
zurückgibt, das das zu zeichnende Rechteck beschreibt. Alle Anweisungen, die mit dem Zeichnen des Widgets verbunden sind, sollen sich in der virtuellen Funktion paintEvent()
befinden, die dieses Ereignis bedient. Das Zeichnen selbst erfolgt mit Hilfe der Klasse QPainter
.
Diese Klasse hat u.a. Methoden zum Zeichnen von Linien, Rechtecken, Ellipsen, Pfaden, Texten und in Pixmaps gespeicherten Bildern. Wenn wir Farben mit dem Alpha-Kanal (alpha-channel) einstellen, können wir Transparenzen zeichnen. Alle Zeichenoperationen können Antialiasing verwenden. QPainter
ist in der Lage, auf Objekten vom Typ QPaintDevice
zu zeichnen. Diese Klasse wird u.a. durch QWidget
, QPixmap
und QPrinter
erweitert.