Helmut Herold: Das Qt-Buch

Größe: px
Ab Seite anzeigen:

Download "Helmut Herold: Das Qt-Buch"

Transkript

1 Helmut Herold: Das Qt-Buch

2

3 Helmut Herold Das Qt-Buch Portable GUI-Programmierung unter Linux / Unix / Windows

4 Alle in diesem Buch enthaltenen Programme, Darstellungen und Informationen wurden nach bestem Wissen erstellt und mit Sorgfalt getestet. Dennoch sind Fehler nicht ganz auszuschließen. Aus diesem Grund ist das in dem vorliegenden Buch enthaltene Programm- Material mit keiner Verpflichtung oder Garantie irgendeiner Art verbunden. Autoren und die SuSE GmbH übernehmen infolgedessen keine Verantwortung und werden keine daraus folgende Haftung übernehmen, die auf irgendeine Art aus der Benutzung dieses Programm-Materials, oder Teilen davon, oder durch Rechtsverletzungen Dritter entsteht. Die Wiedergabe von Gebrauchsnamen, Handelsnamen, Warenbezeichnungen usw. in diesem Buch berechtigt auch ohne besondere Kennzeichnung nicht zu der Annahme, dass solche Namen im Sinne der Warenzeichen- und Markenschutz-Gesetzgebung als frei zu betrachten wären und daher von jedermann verwendet werden dürften. Alle Warennamen werden ohne Gewährleistung der freien Verwendbarkeit benutzt und sind möglicherweise eingetragene Warenzeichen. Die SuSE GmbH richtet sich im Wesentlichen nach den Schreibweisen der Hersteller. Andere hier genannte Produkte können Warenzeichen des jeweiligen Herstellers sein. Dieses Werk ist urheberrechtlich geschützt. Alle Rechte, auch die der Übersetzung, des Nachdruckes und der Vervielfältigung des Buches, oder Teilen daraus, vorbehalten. Kein Teil des Werkes darf ohne schriftliche Genehmigung des Verlages in irgendeiner Form (Druck, Fotokopie, Microfilm oder einem anderen Verfahren), auch nicht für Zwecke der Unterrichtsgestaltung, reproduziert oder unter Verwendung elektronischer Systeme verarbeitet, vervielfältigt oder verbreitet werden. Die Deutsche Bibliothek CIP-Einheitsaufnahme Herold, Helmut: Das Qt-Buch : portable GUI-Programmierung unter Linux/Unix/Windows / Helmut Herold. Nürnberg : SuSE-Press, 2001 ISBN SuSE GmbH, Nürnberg ( Umschlaggestaltung: Fritz Design GmbH, Erlangen Gesamtlektorat: Nicolaus Millin / Dr. Markus Wirtz Fachlektorat: Michael Eicks, Stefan Fent, Thomas Fricke, Bruno Gerz, Ralf Haferkamp, Michael Hager, Harri Porten, Chris Schläger, Lukas Tinkl Satz: LATEX Druck: Kösel, Kempten Printed in Germany on acid free paper.

5 Geleitwort Wenn wir bei Trolltech an Qt denken, so denken wir an ein Werkzeug für real programmers. Dies bedeutet keinesfalls, dass wir noch mit Fortran arbeiten oder unser API nicht dokumentieren. Real programmers sind für uns Profis, die ihre Arbeit gemacht bekommen müssen schnell, effizient und mit wartbarem Code in bestmöglicher Qualität. Real programmers springen nicht auf den letzen Hype auf wie auch immer die Programmiersprache des Monats oder das Dogma der Woche lauten sollten. Für sie zählt Ausführungsgeschwindigkeit, Eleganz, Wartbarkeit, Flexibilität und nicht zuletzt die eigene Effizienz bei der Entwicklung der Programme. Für immer mehr Projekte bedeutet das fast schon automatisch Qt und C. Verglichen mit alternativen Toolkits benötigt eine mit Qt geschriebene Anwendung in der Regel nur einen Bruchteil des Codes, ohne dabei langsamer zu sein. Wohlgemerkt, das gilt bereits für eine einzige Plattform, für cross-platform Anwendungen fällt das Ergebnis für Qt noch viel günstiger aus. Unser Geheimrezept hierfür sind neben der konsequenten Anwendung Objekt-orientierter Techniken sorgfältig gestaltete APIs und Abstraktionen. Ziel ist es, die normale Anwendung einer Klasse so einfach wie nur irgend möglich zu machen, ohne dabei die avanciertere Verwendung zu erschweren. Das setzt voraus, dass sich ein Toolkit nicht als Blackbox präsentiert, sondern als offene Lösung auch die dahinterliegenden Konzepte offenbart. Ein angenehmer Nebeneffekt soll hier nicht verschwiegen werden: Programmieren mit Qt macht einfach Spaß! Zumindest mir ging das vor fünf Jahren so, als ich das Toolkit erstmals als Anwender entdeckte und bis heute hat sich daran nichts geändert. Und solange ich unsere Entwicklungsabteilung in ihrer Freizeit an privaten Qt-basierten Projekten basteln sehe, wird sich daran auch nichts ändern. Viel Spaß also auch Ihnen mit Qt und dem bis dato umfangreichsten gedruckten Werk zur Qt-Programmierung! Eine Bitte noch: Wenn sie einen Fehler in Qt gefunden oder einen Verbesserungsvorschlag zu machen haben, bitte zögern Sie nicht, uns eine Mail auf: zu schicken. Oslo, im Juni 2001 Matthias Ettrich

6

7 Danksagung Zunächst möchte ich einmal Nico Millin und Dr. Markus Wirtz von SuSE PRESS meinen Dank dafür aussprechen, dass sie beim Setzen dieses Buches mit über Seiten nie den Mut verloren und immer nur positiv nach vorne oder sagen wir in diesem Falle besser: nach hinten geblickt haben. Trotz aller Widrigkeiten, die das Setzen eines Buches nun einmal mit sich bringt, war die Zusammenarbeit mit ihnen immer angenehm. Dafür möchte ich mich an dieser Stelle nochmals recht herzlich bedanken. Des weiteren möchte ich mich noch bei meinen Kollegen von SuSE Labs bedanken, die selbst in den größten Stresszeiten stets Zeit fanden, mir bei nervenden Fragen zu helfen, und mir mit Rat und Tat zur Seite standen. Ein dickes Dankeschön an Klaas Freitag, Michael Hager, Stefan Hundhammer, Chris Schläger und Adrian Schroeter. Auch möchte ich mich bei Michael Eicks, Stefan Fent, Thomas Fricke, Bruno Gerz, Ralf Haferkamp und Lukas Tinkl für ihre konstruktiven Beiträge und Anregungen während des Korrekturlesens herzlich bedanken, die ich sehr gerne in dieses Buch eingearbeitet habe. Schließlich möchte ich mich noch bei der norwegischen Firma Trolltech bedanken, ohne die es keine Qt-Bibliothek und somit auch nicht dieses Buch gäbe. Ein dickes Dankeschön an Matthias Ettrich und Harri Porten von Trolltech für ihre Unterstützung, auf die ich gerade in der Endphase der Entstehung dieses Buches angewiesen war. Und natürlich danke ich meiner Frau Micha, die meiner Sucht zum Schreiben dieses Buches mit mehr Verständnis und Entbehrung entgegenkam als ich verdient habe. Meinen beiden Kindern Niklas und Sascha möchte ich an dieser Stelle noch versprechen, dass wir jetzt wieder öfter Angeln gehen. Weisendorf-Neuenbürg, im Juni 2001 Dr. Helmut Herold

8

9 Die Themen im Überblick Einleitung Einführung in die Objektorientierung und C Allgemeines zu Qt Grundlegende Konzepte und Konstrukte von Qt Die wesentlichen Qt-Widgets Zuordnung und Layout von Widgets Vordefinierte Dialogfenster Portable Datei- und Directory-Operationen Vordefinierte Datentypen und Datenstrukturen (Containerklassen) Datenaustausch zwischen verschiedenen Applikationen Datum, Zeit und Zeitschaltuhren Graphik Bildformate und Cursorformen Animationen und Sounds Konsistente Eingaben und reguläre Ausdrücke Tastaturfokus Ereignisbehandlung (Event-Handling) Signale und Slots IX

10 Die Themen im Überblick 18 Erstellen eigener Widgets Thread-Programmierung und -Synchronisation Mehrsprachige Applikationen und Internationalisierung Test- und Debugging-Möglichkeiten Netzwerkprogrammierung mit Qt Blockierungsfreie Datenübertragung im Hintergrund Parsen von XML-Dokumenten Qt-Programmierung mit anderen Bibliotheken und Sprachen Der Qt GUI-Designer Erstellen von Qt-Programmen mit KDevelop Das Tool tmake X

11 Inhaltsverzeichnis Einleitung 1 1 Einführung in die Objektorientierung und C Objektorientierung in der realen Welt Objektorientierung in der Software Nicht-objektorientierte Erweiterungen in C Zeilen-Kommentare mit // Variablen-Deklarationen (auch im Anweisungsteil) Default-Argumente bei Funktionsaufrufen Überladen von Funktionen Inline-Funktionen Referenzen/Referenz-Operator Neue Ein- und Ausgabebibliothek Operatoren new und delete Neuer Datentyp bool Weglassen der Schlüsselwörter struct, union und enum bei Deklarationen Funktionen in Strukturen Erster wesentlicher Schritt zur Objektorientierung Beispiel: Mastermind gegen Computer Objektorientierte Erweiterungen in C Wichtige Begriffe aus der Welt der Objektorientierung Klassen Überladen von Operatoren Vererbung Templates Allgemeines zu Qt Was ist Qt und warum Qt? Der Begriff Widget Die Qt-Online-Dokumentation im HTML-Format Die Qt-Dokumentation als Postscript-Datei Kompilieren von Qt-Programmen XI

12 Inhaltsverzeichnis 3 Grundlegende Konzepte und Konstrukte von Qt Erstes Qt-Programm mit Text und Buttons Mehr zum Signal-Slot-Konzept von Qt Schiebebalken und Buttons zum Erhöhen/Erniedrigen von LCD-Nummern Schiebebalken und Buttons zum Ändern der Schriftgröße mit Textanzeige Regeln für die Deklaration eigener Slots und Signale Die Klasse QString für das Arbeiten mit Zeichenketten unter Qt Farbmodelle, Farbgruppen und Paletten im Qt Farbmodelle (QColor) Farbgruppen (QColorGroup) Palette eines Widget (QPalette) Beispiele Malprogramm mit Menüs, Events und mehr Eine erste einfache Version eines Malprogramms Eine zweite, etwas erweiterte Version des Malprogramms Eine dritte Version des Malprogramms mit Menüs Eine vierte Version des Malprogramms mit Laufbalken Eine fünfte Version des Malprogramms mit einigen netten Erweiterungen Eine letzte Version des Malprogramms mit Speichern und Laden von Dateien Die wesentlichen Qt-Widgets Allgemeine Widget-Methoden und -Parameter Allgemeine Widget-Methoden Parameter-Konventionen für die meisten Konstruktoren Der Widget-Stil Buttons Pushbuttons (QPushButton) Radiobuttons (QRadioButton) und Checkboxen (QCheck- Box) Pushbuttons mit der Wirkungsweise von Radiobuttons Gruppieren von Buttons (QButtonGroup) Beispiel zu Buttons Beispiel zu Gruppen von Buttons Beispiel zu Popupmenüs bei Pushbuttons Übung: Synchronisieren von Radio- mit Togglebuttons Auswahl-Widgets (List- und Komboboxen) Listboxen (QListBox) Komboboxen (QComboBox) Beispiel zu List- und Komboboxen Übung: Eingabe von Daten über List- und Komboboxen Schiebebalken-, Drehknopf- und Spinbox-Widgets Schiebebalken (QSlider) XII

13 Inhaltsverzeichnis Drehknopfeinstellungen (QDial) Spinboxen (QSpinBox) Beispiel zu Schiebebalken und Spinboxen Beispiel zur Klasse QDial Übung: Größeneinstellung eines Rechtecks über Schiebebalken und Spinboxen Widgets zum Anzeigen von Informationen Einfache Labels (QLabel) Komfortable Textanzeige (QTextView, QTextBrowser) Segment-LCD-Anzeige (QLCDNumber) Beispiel zu Labels: Anzeige von Graphikbildern Beispiel zur Anzeige von RichText Beispiel zu LCD-Zahlen: Synchronisierte Darstellung in verschiedenen Zahlensystemen Übung: Mausposition als LCD-Nummer und als Fadenkreuz Texteingabefelder Einzeilige Texteingabefelder (QLineEdit) Mehrzeilige Texteingabefelder (QMultiLineEdit) Beispiel zu Texteingabefeldern: Potenzieren von Zahlen Weiteres Beispiel zu einzeiligen Texteingabefeldern Übung: Synchronisierte Darstellung in verschiedenen Zahlensystemen Menüs Die Basisklasse für Menüs (QMenuData) Beispiel: Auswahl einer Farbe über ein Menü Festlegen von Beschleunigern (Accelerators) Popupmenüs, deren Inhalt sich dynamisch ändert Die Menüleiste (QMenuBar) Kontextmenüs Beispiel zu Menüs Übung: Einstellen des Font über Menüs, Beschleuniger oder Kontextmenüs Hauptfenster mit Menüs, Werkzeugleisten, Statuszeile und Hilfstexten Das Hauptfenster (QMainWindow) Werkzeugleisten (QToolBar und QToolButton) Einfaches Beispiel zu QMainWindow mit Menüs und Werkzeugleisten Kurze und längere Hilfstexte (QToolTip, QToolTipGroup und QWhatsThis) Beispiel: Dynamische Tooltips (Möglichkeit 1) Beispiel: Dynamische Tooltips (Möglichkeit 2) Statuszeilen (QStatusBar) Beispiel zu QMainWindow mit Werkzeugleisten, Statuszeile und Hilfstexten Übung: Einfacher Texteditor XIII

14 Inhaltsverzeichnis 4.10 Füllbalken Horizontaler Füllbalken (QProgressBar) Dialog mit Text, Füllbalken und Cancel-Button (QProgress- Dialog) Beispiel: Demoprogramm zu QProgressDialog Übung: Steuern eines Füllbalkens über Schiebebalken Übung: Würfeln der Gaußschen Glockenkurve Listenansichten Die Klasse QListView Die Klasse QListViewItem Die Klasse QListViewItemIterator Einfaches Beispiel zu einer Listenansicht Beispiel: Directorybrowser in Form einer Listenansicht Übung: Qt-Klassenhierarchie in einer Listenansicht Fenster mit Laufbalken (Scrollviews) Die Klasse QScrollView Vorgehensweisen abhängig von Fensterfläche Beispiel zu den unterschiedlichen Vorgehensweisen Die Klasse QScrollBar Beispiel: Scrollen eines Bildes mit QScrollBar Übung: Geschachtelte Fenster mit Laufbalken Tabellen Die Klasse QTableView für einfache Tabellen Beispiel zu QTableview: Multiplikationsaufgaben Die Klasse QTable für Tabellen im Spreadsheet-Stil Die Klasse QHeader Die Klassen QTableItem und QTableSelection Beispiel: Spreadsheet für eine Personalverwaltung Übung: Tabelle mit Multiplikationsaufgaben Zuordnung und Layout von Widgets Zuordnung von Widgets untereinander Die Klasse QFrame Die Klasse QGroupBox Die Klasse QButtonGroup Die Klasse QSplitter Die Klasse QWidgetStack Layout von Widgets Einfaches Layout mit QHBox, QVBox und QGrid Fortgeschrittenes Layout mit QLayout Benutzerdefinierte Layouts Vordefinierte Dialogfenster Die Basisklasse QDialog Klasse QColorDialog zur Auswahl einer Farbe Klasse QFileDialog zur Auswahl einer Datei XIV

15 Inhaltsverzeichnis 6.4 Klasse QFontDialog zur Auswahl eines Font Klasse QMessageBox für Mitteilungen Klasse QTabDialog zur Stapelung von Widgets im Karteikartenformat Klasse QWizard zum Blättern in einer vorgegebenen Menge von Widgets Klasse QPrinter zum Drucken mit möglichen Druckereinstellungen Klasse QInputDialog für einfache Benutzereingaben Klasse QProgressDialog zur Fortschrittsanzeige in einem Prozentbalken Portable Datei- und Directory-Operationen Die Basisklasse QIODevice für Zugriffe auf E/A-Geräte Klasse QFile für Datei-Operationen Klasse QBuffer für Speicherzugriffe wie bei einem E/A-Gerät Die Klassen QTextStream und QDataStream Klasse QTextStream zum Lesen und Schreiben von Text in Dateien Klasse QDataStream zum plattformunabhängigen Lesen und Schreiben in Dateien Klasse QFileInfo zum Erfragen von Informationen zu Dateien Klasse QDir für Directory-Operationen Vordefinierte Datentypen und Datenstrukturen (Containerklassen) Vordefinierte Datentypen (QPoint, QSize und QRect) Die Klasse QPoint Die Klasse QSize Die Klasse QRect Übung: Durchschnitt und umschließendes Rechteck von zwei Rechtecken Data-Sharing Arrays Die Klasse QArray Die Klasse QVector Die Klasse QByteArray Die Klasse QBitArray Die Klasse QPointArray Hashtabellen und zugehörige Iterator-Klassen Die Klasse QDict QDictIterator - Eine Iterator-Klasse für QDict Die Klassen QAsciiDict, QPtrDict, QAsciiDictIterator und QPtrDictIterator Die Klassen QIntDict und QIntDictIterator Die Klasse QCache QCacheIterator Eine Iterator-Klasse für QCache 561 XV

16 Inhaltsverzeichnis Die Klassen QAsciiCache und QAsciiCacheIterator Die Klassen QIntCache und QIntCacheIterator Die Klasse QMap für wertebasierende Hashtabellen Übung: Cross-Reference-Liste für C-Programme Listen und zugehörige Iterator-Klassen Die Klasse QList QListIterator Eine Iterator-Klasse für QList Klasse QValueList Eine wertebasierende Liste Die Iterator-Klassen QValueListIterator und QValue- ListConstIterator Die Klasse QStringList Die Klassen QStrList und QStrIList Übung: Das Josephus-Spiel Stacks (LIFO-Strategie) Die referenzbasierende Klasse QStack Die wertebasierende Klasse QValueStack Übung: Umwandlung einer Dezimalzahl in Dualzahl Queues (FIFO-Strategie) Die Klasse QQueue Beispiel: Simulation einer Warteschlange Übung: Realisierung einer Warteschlange Datenaustausch zwischen verschiedenen Applikationen Verwendung des Clipboard Die Klasse QClipBoard Beispiel: Austausch von Texten über das Clipboard Beispiel: Austausch von Bildern über das Clipboard Übung: Zufälliges Austauschen von Bildern über das Clipboard Drag-and-Drop Drag-and-Drop von Text oder Bildern in Qt Drag-and-Drop in Verbindung mit dem Clipboard Definieren von eigenen Typen für Drag-and-Drop Die Klasse QUriDrag zum Austausch von Dateinamen Übung: Zusammenstellen eines Kartenblattes mit Drag-and- Drop Datum, Zeit und Zeitschaltuhren Die Klasse QDate Beispiel: Demonstrationsprogramm zur Klasse QDate Beispiel: Tagesdifferenz zwischen zwei Daten Übung: Ermitteln des Ostertermins für ein Jahr Die Klasse QTime Beispiel: Addition von zwei Zeiten Beispiel: Ein Reaktionstest Übung: Anzeige der aktuellen Zeit mit Fortschrittsbalken 628 XVI

17 Inhaltsverzeichnis 10.3 Die Klasse QDateTime Beispiel: Ausgeben der Sekunden und Tage bis zu fixen Daten Übung: Automatische Arbeitszeiterfassung Zeitschaltuhren (Timer) Die Klasse QTimer Timer-Events Übung: Realisierung einer Ampelsteuerung Graphik Allozieren von Farben Farballozierung mit Methoden der Klasse QColor Farballozierung mit Methoden der Klasse QApplication Grundlegendes zur Klasse QPainter Konstruktoren und Methoden der Klasse QPainter Beispiele Einstellungen für QPainter-Objekte Einstellen des Zeichenstifts Festlegen eines Füllmusters Festlegen eines neuen Zeichenfonts Beispiel: Zufällige Zeichenstifte mit allen Füllmustern Übung: Interaktives Einstellen von Stift und Füllmuster Positionieren und Ausgeben von Figuren und Text Positionieren Zeichnen geometrischer Figuren Ausgeben von Text Alternatives Ausgeben von Figuren Funktionen aus <qdrawutil.h> Beispielprogramm zu den Funktionen aus <qdrawutil.h> Übung: Game of Life Transformationen Einfache World-Transformationen World-Transformationen mit der Klasse QWMatrix View-Transformationen Clipping Festlegen von Clipping-Regionen Die Klasse QRegion Beispielprogramm zu Clipping Übung: Vorbeifliegende Gegenstände an Fensterwand QPainter-Zustand sichern und wiederherstellen Die QPainter-Methoden save() und restore() Beispiel: Drehen einer sich ständig ändernden Figur Übung: QPainter-Zustände im Stack Flimmerfreie Darstellung Ausschalten der Hintergrundfarbe Vermeiden überflüssigen Zeichnens XVII

18 Inhaltsverzeichnis Doppel-Pufferung Die QCanvas-Klassen Die Klasse QCanvas Die Klasse QCanvasItem Die Klasse QCanvasLine Die Klasse QCanvasRectangle Die Klasse QCanvasEllipse Die Klasse QCanvasPolygon Die Klasse QCanvasPolygonalItem Die Klasse QCanvasSprite Die Klasse QCanvasText Die Klasse QCanvasPixmap Die Klasse QCanvasPixmapArray Die Klasse QCanvasView Demoprogramm zu den QCanvas-Klassen Übung zu den QCanvas-Klassen Bildformate und Cursorformen Pixmap-Klassen Format einer Pixmap Die Klasse QPixmap Die Klasse QPixmapCache Die Klasse QBitmap Beispiel: Erstellen eines Screenshot durch Ziehen der Maus Übung: Screenshot vom Bildschirm oder eines Teilbereichs Die Klasse QCursor Konstruktoren und Methoden der Klasse QCursor Beispiel zu vor- und benutzerdefinierten Cursorformen Übung: Ändern des Mauscursor bei einem Mausklick Die Klassen QImage und QImageIO Konstruktoren und Methoden der Klasse QImage Routinen zum Setzen bzw. Erfragen einzelner Pixel Die Klasse QImageIO für benutzerdefinierte Bildformate Beispiel: Einfache Bildbearbeitung Übung: Erweiterte Bildbearbeitung Die Klasse QPicture Konstruktoren und Methoden der Klasse QPicture Beispiel: Demoprogramm zur Klasse QPicture Animationen und Sounds Animationen mit der Klasse QMovie Konstruktoren und Methoden der Klasse QMovie Beispiel: Abspielen von Filmen Beispiel: Einstellen der Abspielgeschwindigkeit Übung: Anzeigen einzelner Frames (Bilder) eines Films Sound mit der Klasse QSound XVIII

19 Inhaltsverzeichnis Konstruktor und Methoden der Klasse QSound Beispiel: Demoprogramm zur Klasse QSound Übung: Auswahl einer Sound-Datei über QFileDialog Konsistente Eingaben und reguläre Ausdrücke Konsistente Eingaben mit Klasse QValidator Die Basisklasse QValidator Die Klasse QIntValidator Die Klasse QDoubleValidator Reguläre Ausdrücke (Klasse QRegExp) Unterschiedliche Arten von regulären Ausdrücken Escape-Sequenzen Konstruktoren und Methoden der Klasse QRegExp Tastaturfokus Einstellen und Erfragen von Fokusregeln Reihenfolge beim Wechseln des Tastaturfokus mit der Tabtaste Ereignisbehandlung (Event-Handling) Allgemeines zu Events Die Basisklasse QEvent und die davon abgeleiteten Event-Klassen Die Basisklasse QEvent Mal-Events (QPaintEvent) Maus-Events (QMouseEvent und QWheelEvent) Tastatur-Events (QKeyEvent) Timer-Events (QTimerEvent) Fokus-Events (QFocusEvent) Größenänderungs-Events (QResizeEvent) Positionsänderungs-Events (QMoveEvent) Eintritts- und Austritts-Events Versteck-, Sichtbarkeits- und Schließ-Events (QHideEvent, QShowEvent, QCloseEvent) Subwidget-Events (QChildEvent) Drag-and-Drop-Events (QDragEnterEvent, QDragMove- Event, QDragLeaveEvent, QDropEvent) Event-Filter Senden eigener Events Benutzerdefinierte Events (QCustomEvent) Signale und Slots Verbindung zwischen einem Signal und einer Slotroutine Verbindung zwischen einem Signal und einem anderen Signal Auflösen bzw. temporäres Ausschalten von bestehenden Signal-Slot- Verbindungen Verbinden mehrerer Buttons mit einer Slotroutine Senden eigener Signale mit QSignal XIX

20 Inhaltsverzeichnis 18 Erstellen eigener Widgets Grundlegende Vorgehensweise beim Entwurf eigener Widgets Beispiel: Implementieren eines Funktionsplotters Beschreibung des Funktionsplotters Headerdatei für den Funktionsplotter Implementierung des Funktionsplotters Beispiel: Plotten einer Sinusfunktion Beispiel: Plotten einer Funktion, die der Benutzer interaktiv eingibt Übung: Plotten der Funktion 1-exp(0.5x) und deren Ableitung Beispiel: Implementieren einer Bildertabelle Beschreibung des Bildertabellen-Widget Headerdatei für das Bildertabellen-Widget Implementierung das Bildertabellen-Widget Beispiel: Ein Memory-Spiel Beispiel: Ein Puzzle-Spiel Beispiel: Ein Poker-Spiel Übung: Ein Bilderbrowser für Dias Thread-Programmierung und -Synchronisation Die Klasse QThread Synchronisation von Threads mit QMutex Synchronisation von Threads mit QSemaphore Synchronisation von Threads mit QWaitCondition Übung: Zuteilung von Plätzen in einem Speiseraum Mehrsprachige Applikationen und Internationalisierung Die Klasse QString für Unicode Automatische Übersetzung in andere Sprachen Automatische Anpassung an lokale Besonderheiten Konvertierung von Text-Kodierungen Übung: Landabhängiges Einblenden eines Datums Test- und Debugging-Möglichkeiten Testausgaben mit qdebug(), qwarning() und qfatal() Die Makros ASSERT() und CHECK_PTR() Debuggen mittels Objektnamen Übung: Testausgaben in eine Log-Datei Netzwerkprogrammierung mit Qt Protokollunabhängige Netzwerkprogrammierung Die Klasse QUrlOperator Die Klasse QUrl Die Klasse QUrlInfo Die Klasse QNetworkOperation XX

21 Inhaltsverzeichnis Beispiel: Herunterladen einer Datei von einem FTP-Server mit Fortschrittsanzeige Übung: Gleichzeitiges Herunterladen mehrerer Dateien mit Fortschrittsanzeigen Implementieren eigener Netzwerkprotokolle mit QNetworkProtocol Vorgehensweise beim Implementieren eines eigenen Netzwerkprotokolls Die Klasse QNetworkProtocol Die Klasse QFtp Die Klasse QLocalFs Socket-Programmierung Die Klasse QSocket Die Klasse QSocketDevice Die Klasse QServerSocket Beispiel: Ein einfacher http-dämon Beispiel: Einfache Implementierung des nntp-protokolls Low-level Socket-Programmierung Die Klasse QSocketNotifier Die Klasse QHostAddress DNS-Lookups mit der Klasse QDns Blockierungsfreie Datenübertragung im Hintergrund Die Klasse QDataSource Die Klasse QDataSink Die Klasse QDataPump Beispiel: Demoprogramm zu den Klassen QDataSource, QData- Sink und QDataPump Übung: Zählen der 0- und 1-Bits in Dateien Parsen von XML-Dokumenten SAX2 und die zugehörigen Qt-Klassen Die SAX2-Schnittstelle von Qt Die Klassen der SAX2-Schnittstelle von Qt Beispiel: Plotten einer Funktion über ein XML-Dokument Beispiel: Anzeigen von XML-Dokumenten im Richtext-Format DOM Level 1 und die zugehörigen Qt-Klassen Die DOM-Schnittstelle von Qt Die Klassen der DOM-Schnittstelle von Qt Beispiel: Plotten einer Funktion über ein XML-Dokument Beispiel:Anzeigen von XML-Dokumenten im Richtext-Format Übung: Plotten einer Funktion als Linie oder in Balkenform über ein XML-Dokument XXI

22 Inhaltsverzeichnis 25 Qt-Programmierung mit anderen Bibliotheken und Sprachen OpenGL-Programmierung mit Qt Die Klasse QGLWidget Die Klasse QGLContext Die Klasse QGLFormat Beispiel: Drehen eines Quaders in x-, y- und z-richtung Übung: Drehen einer Pyramide in x-, y- und z-richtung Qt-Programmierung mit Perl Ein erstes einfaches PerlQt-Beispiel Kurze Beschreibung von PerlQt Beispiele zur PerlQt-Programmierung Erstellen von Netscape Plugins Herunterladen und Installieren des Plugin SDK Die Qt Netscape-Plugin Erweiterung Kompilieren, Installieren und Testen von Plugins Beispiele für mit Qt erstellte Netscape Plugins Der Qt GUI-Designer Erstellen einer ersten einfachen Applikation mit dem Qt-Designer Layout-Management im Qt-Designer Ändern der Tab Order Weitere GUI-Builder Erstellen von Qt-Programmen mit KDevelop Das Tool tmake Allgemeines zu tmake Installation von tmake Einfache Benutzung von tmake Konfiguration des Makefile Variablen bei den einzelnen Templates Setzen von Projektvariablen Aufruf von tmake Das Tool progen XXII

23 Einleitung Ursachen erkennen, das eben ist Denken, und dadurch allein werden Empfindungen zu Erkenntnissen und gehen nicht verloren, sondern werden wesenhaft und beginnen auszustrahlen. Herrmann Hesse Dieses Buch stellt die von der norwegischen Firma Trolltech entwickelte C -Klassenbibliothek Qt (Version 2.2) vor, die eine einfache und portable GUI-Programmierung ermöglicht. Mit Qt entwickelte Programme sind sofort ohne zusätzlichen Portierungsaufwand sowohl unter allen Unix- wie auch unter allen Windows- Systemen lauffähig. Sie müssen lediglich mit den entsprechenden Compilern (Visual C oder Borland C unter Windows-Systemen oder dem auf dem jeweiligen Unix-System angebotenen cc-compiler) kompiliert und gelinkt werden. In Zukunft wird die Portabilität von entwickelter Software wohl immer wichtiger werden, denn warum sollte man ein Programm entwickeln, das nur unter Windows- Systemen lauffähig ist, und sich damit freiwillig aus dem Markt der Millionen von Unix- und Linux-Systemen ausschließen. Der umgekehrte Fall gilt selbstverständlich auch. Es stellt sich hier natürlich die Frage, warum man bei Neuentwicklungen nicht gleich die Programmiersprache Java verwenden sollte, die ebenfalls das Erstellen portabler Programme ermöglicht. Nun, Java hat sicherlich wie Qt den Vorteil der Portabilität, aber die Ablaufgeschwindigkeit von Java-Programmen kann nicht mit der von Qt-Programmen mithalten. Außerdem sollte man berücksichtigen, dass Qt eine C -Bibliothek ist, und schon von Programmierern, die die Programmiersprache C beherrschen und nur grundlegende Kenntnisse in C besitzen, verwendet werden kann. Und die Anzahl von Softwareentwicklern mit diesem Profil ist sehr, sehr groß. Voraussetzungen des Lesers Ein gutes Beherrschen der Programmiersprache C wird in diesem Buch ebenso vorausgesetzt wie die Kenntnis der wesentlichen C-Standardfunktionen. Wie bei jedem fortgeschrittenen Programmierkurs kann auch hier ein Basiswissen über grundlegende Datenstrukturen und Algorithmen nur von Vorteil sein. 1

24 Einleitung Ein paar Worte zu diesem Buch Bei einer so mächtigen Bibliothek wie Qt mit Hunderten von Klassen und Tausenden von Methoden, die zum Teil an Subklassen weitervererbt werden, stellt sich natürlich die Frage, wie man so etwas vermitteln kann. Ein bloßes Vorstellen der Klassen mit ihren Methoden und Datentypen wäre wenig sinnvoll, da der Neuling zum einen von der Vielzahl der Informationen erschlagen würde und zum anderen nicht das Zusammenspiel der einzelnen Klassen, was wohl für die Praxis mit am wichtigsten ist, kennenlernen würde. Hier wurde daher folgende Vorgehensweise gewählt: Vorstellen der wesentlichen Konstrukte, Klassen und Methoden von Qt Es werden nicht alle Klassen, sondern nur die wesentlichen Klassen sowie dort nur die wichtigsten Methoden vorgestellt. So soll vermieden werden, dass der Leser sich durch die Vielzahl der Informationen überfordert fühlt. Eine vollständige Referenz zu Qt befindet sich in der bei der Qt-Software mitgelieferten Online-Dokumentation, ohne die auch erfahrene Qt-Programmierer kaum auskommen. Zusammenfassen der Klassen zu funktionalen Themengebieten Eine Beschreibung der Klassen in alphabetischer Reihenfolge würde dazu führen, dass der Leser die Klassen ähnlich dem Lernen nach einem Lexikon nur unstrukturiert kennenlernen würde. Um dies zu vermeiden, ist dieses Buch nach Themengebieten strukturiert, in denen jeweils die Klassen zusammengefasst sind, die artverwandt sind und Ähnliches leisten. Dieses didaktische Prinzip Vom Problem (Aufgabenstellung) zur Lösung (Klasse) bringt zwei Vorteile mit sich: Zum einen wird der Leser in einer strukturierten Form an die mächtige Qt-Bibliothek herangeführt, und zum anderen ermöglicht dieser Aufbau ein schnelles Nachschlagen beim späteren praktischen Programmieren, wenn zu einer gewissen Aufgabenstellung entsprechende Informationen benötigt werden. Beispiele, Beispiele und noch mehr Beispiele Um das Zusammenspiel der einzelnen Klassen und Methoden aufzuzeigen, werden immer wieder Beispiele (über 250 Beispielprogramme mit etwa Codezeilen) eingestreut, um typische Konstrukte oder Programmiertechniken aufzuzeigen, die es ermöglichen, später beim selbstständigen Programmieren in diesen Beispielprogrammen nachzuschlagen, wenn ähnliche Problemstellungen vorliegen. Es sei an dieser Stelle darauf hingewiesen, dass sich so bisweilen auch umfangreichere Programmlistings ergeben, die vielleicht zunächst etwas abschreckend wirken; aber praxisnahes Programmieren, das durch dieses Buch vermittelt werden soll, hat eben selten etwas mit Zwanzig- Zeilern zu tun. Um diese Listings nicht allzu groß werden zu lassen, werden die Methoden oft inline definiert, was hoffentlich verziehen wird. Übungen am Ende der Kapitel Um den Leser seine in einem Kapitel erworbenen Kenntnisse selbst testen zu lassen, befinden sich am Ende nahezu jeden Kapitels Übungsprogramme, die teilweise sehr anspruchsvoll sind. Bei einigen dieser nahezu 100 Übungspro- 2

25 Einleitung gramme (mit über Codezeilen) muss der Leser eventuell in der Qt- Online-Dokumentation nachschlagen, um die Aufgabenstellungen zu lösen. Dies ist beabsichtigt, da man in der späteren Programmierpraxis auch selbstständig arbeiten muss und kaum ohne ein Nachschlagen in der Qt-Online- Dokumentation auskommen wird. Übersicht über dieses Buch Das Buch gliedert sich in folgende Teile: Kapitel 1 gibt eine kurze Einführung in die Welt der Objektorientierung und insbesondere in die wichtigsten Konzepte der objektorientierten Sprache C, da solche grundlegenden Kenntnisse für eine Programmierung mit der objektorientierten C -Klassenbibliothek erforderlich sind. Leser, die mit der Objektorientierung und C vertraut sind, können dieses Kapitel übergehen und unmittelbar mit Kapitel 2 fortfahren. Kapitel 2 klärt zunächst einmal, was Qt überhaupt ist und welche Vorteile es aufweist, bevor der wichtige Qt-Begriff Widget eingeführt wird. Die folgenden Absätze gehen dann kurz auf die bei Qt mitgelieferte Dokumentation ein, bevor abschließend auf die Generierung von Qt-Programmen mit make sowie mit dem eigens von den Qt-Entwicklern angebotenen Tool tmake zur automatischen Erstellung von Makefiles eingegangen wird. Kapitel 3 gibt dann anhand von Beispielen einen Überblick über die wesentlichen Konzepte und Konstrukte von Qt. Es zeigt zunächst den grundsätzlichen Aufbau eines Qt-Programms, bevor es das wichtige Signal-Slot-Konzept von Qt detaillierter vorstellt. Ebenso wird in diesem Kapitel die Klasse QString vorgestellt, welche eine Abstraktion zu Unicode-Text und zum String-Konzept im klassischen C ist. Ein eigener Abschnitt stellt dann die von Qt verwendeten Farbmodelle vor und klärt, was Farbgruppen sind und wie Farbpaletten für Widgets geändert werden können. Im letzten, etwas umfangreicheren Abschnitt dieses Kapitels wird schließlich ein kleines Malprogramm zum Zeichnen mit der Maus auf dem Bildschirm erstellt, das schrittweise immer mehr erweitert wird, indem Menüs und Laufbalken hinzugefügt werden. In seiner letzten Version ist es sogar möglich, die gemalten Bilder zu speichern und wieder neu zu laden. Kapitel 4 gibt einen Überblick über die wichtigsten von Qt angebotenen Widgets. Die einzelnen Widgets sind in diesem Kapitel nach Themengebieten organisiert, in denen jeweils die Klassen zusammengefasst sind, die artverwandt sind und Ähnliches leisten. Kapitel 5 zeigt die unterschiedlichen Möglichkeiten des Layout und der Zuordnung von Widgets, wie sie von Qt angeboten werden. Kapitel 6 beschreibt die von Qt vordefinierten Dialogfenster, die für typische Kommunikationen mit dem Benutzer, wie z. B. Auswahl einer bestimmten Farbe 3

26 Einleitung 4 oder einer Datei, ausgelegt sind. Diese vordefinierten Dialogfenster nehmen dem Qt-Programmierer viel Arbeit ab, da sie schon mit entsprechenden Auswahlmöglichkeiten und/oder Buttons versehen sind. Kapitel 7 stellt dann die von Qt angebotenen Klassen für Datei- und Verzeichnis- Operationen vor, die nicht nur plattformunabhängig, sondern auch einfach zu verwenden sind. Kapitel 8 stellt zunächst die von Qt vordefinierten Datentypen (Klassen) QPoint, QSize und QRect vor, die vor allen Dingen beim Zeichnen geometrischer Objekte in einer Malfläche benötigt werden. Bevor dieses Kapitel dann mit der detaillierteren Beschreibung der einzelnen von Qt angebotenen Template- Klassen für typische Datenstrukturen wie z. B. Arrays oder Listen beginnt, stellt es zunächst nochmals kurz grundlegende Konzepte von C vor, die für das Verständnis der nachfolgenden Abschnitte notwendig sind. Dabei werden zunächst Konzepte wie explizites und implizites Sharing oder tiefe Kopie (deep copy) und flache Kopie (shallow copy) geklärt, bevor die entsprechenden Template-Klassen und Methoden aufgezählt werden, die das jeweilige Konzept verwenden. Kapitel 9 zeigt, wie unterschiedliche Applikationen direkt untereinander Daten unter Verwendung des global verfügbaren Clipboard bzw. mittels der Drag-and- Drop-Technik austauschen können. Kapitel 10 stellt Klassen vor, mit denen man Datums- und Zeitoperationen durchführen oder sich aber auch Zeitschaltuhren (Timer) einrichten kann, die in festgelegten Zeitperioden immer wieder Signale an das eigene Programm schicken. Kapitel 11 stellt zunächst die Möglichkeiten der Farballozierung mit Qt vor, bevor es sich tiefergehend mit den mächtigen Grafik-Klassen von Qt beschäftigt, die alles zeichnen lassen, von einfachen Linien bis zu komplexen Figuren wie Kuchenstücke oder andere geometrische Figuren. Daneben zeigt dieses umfangreichere Kapitel, wie Grafiken mit Qt auch transformiert, z. B. vergrößert oder gedreht werden können. Ein eigenes Unterkapitel stellt dann noch einige Techniken vor, mit denen man Flimmern beim Neuzeichnen eines Bildes vermeiden oder zumindest reduzieren kann. Der letzte Abschnitt stellt schließlich noch die QCanvas-Klassen vor, mit denen Qt einen weiteren Satz von Klassen für zweidimensionale Grafiken zur Verfügung stellt. Diese erlauben es, grafische Elemente schneller zeichnen zu lassen, und sie benötigen auch wenig Speicher. Neben weiteren Vorteilen erlauben diese Klassen auch mehrere Ansichten der gleichen Grafikfläche. Kapitel 12 stellt die von Qt unterstützen Bildformate und Cursorformen vor. Dazu geht es zunächst auf die Pixmap-Klassen ein, die für Zeichnungen ausgelegt und optimiert sind. Im nächsten Abschnitt wird dann die Klasse QCursor behandelt, mit der man dem Mauscursor ein spezielles Aussehen geben kann. Der dritte Abschnitt stellt mit der Klasse QImage die zweite Klasse neben

27 Einleitung den Pixmap-Klassen vor, die von Qt für die Bildbearbeitung angeboten wird. Während die Pixmap-Klassen für Zeichnungen ausgelegt und optimiert sind, ist die Klasse QImage für E/A, direkte Pixel-Zugriffe und -Manipulationen geeignet, da sie ein hardwareunabhängiges Pixmap-Format verwendet. Im letzten Abschnitt dieses Kapitels wird noch die Klasse QPicture vorgestellt, die es ermöglicht, Mal-Kommandos aufzuzeichnen und später wieder ausführen zu lassen. Kapitel 13 geht auf Animationen und Sounds ein und zeigt, wie man mit den eigenen von Qt angebotenen Klassen animierte Bilder oder eben Sound-Dateien abspielen kann. Kapitel 14 zeigt zunächst, wie man falsche Benutzereingaben verhindern kann, bevor es die von Qt unterstützten regulären Ausdrücke vorstellt. Kapitel 15 behandelt den Tastaturfokus, der immer nur auf ein Eingabeelement eingestellt sein kann. Den Tastaturfokus besitzt immer das Eingabeelement, das gerade Eingaben von der Tastatur entgegennehmen kann. Der Tastaturfokus kann üblicherweise mit der Tab -Taste auf das nächste Eingabeelement bzw. mit der Tab -Taste bei gleichzeitig gedrückter Shift -Taste auf das vorherige Eingabeelement verschoben werden. Ebenso kann man üblicherweise den Tastaturfokus direkt auf ein Eingabeelement einstellen, indem man auf dieses mit der Maustaste klickt. Kapitel 16 erläutert zunächst einmal die grundsätzliche Vorgehensweise von Qt beim Auftreten von Events, bevor es im nächsten Abschnitt die Basisklasse QEvent und alle von ihr abgeleiteten Event-Klassen vorstellt. Der nächste Abschnitt behandelt dann so genannte Event-Filter. Ein Event-Filter ist ein Objekt, das alle Events für andere Objekte empfängt. Dieses Objekt kann dann entscheiden, ob es auf die empfangenen Events selbst reagiert und/oder die empfangenen Events an die entsprechenden anderen Objekte weiterleitet oder nicht. In den beiden letzten Abschnitten dieses Kapitels wird dann das Senden eigener Events und die Bearbeitung benutzerdefinierter Events vorgestellt. Kapitel 17 stellt das Signal-Slot-Konzept, das zwar bereits zu Beginn kurz beschrieben und in den Beispielen der vorherigen Kapitel auch ständig verwendet wurde, nochmals vollständig vor, wobei es auch einige bisher noch nicht behandelte Aspekte des Signal-Slot-Konzepts zeigt. Kapitel 18 zeigt, wie man sich eigene Widget-Klassen erstellen kann. Dazu stellt dieses Kapitel zunächst einige wichtige Punkte vor, die dabei zu beachten sind, bevor es anhand von zwei umfangreicheren Beispielen (Funktionsplotter und Tabelle von Bildern) das Erstellen eigener Widgets verdeutlicht. Kapitel 19 stellt zunächst die von Qt angebotene plattformunabhängige Thread- Programmierung und -Synchronisation vor. Dazu stellt es zunächst die für Threads zu verwendende Klasse QThread vor, bevor es Klassen vorstellt, mit denen gleichzeitige laufende Threads synchronisiert werden können. 5

28 Einleitung 6 Kapitel 20 zeigt, wie man mehrsprachige und international verwendbare Qt-Programme erstellen kann. So entwickelte Qt-Applikationen lassen sich leicht und ohne viel Aufwand an länder- und kulturspezifische Gegebenheiten anpassen, so dass der Benutzer dieser Applikation entsprechend seinen Gewohnheiten die entsprechende Sprache, Zeichenkodierung und -darstellung verwenden kann. Kapitel 21 stellt zum einen Funktionen und Makros vor, mit denen man in einem Programm Testausgaben und automatische Verifizierungen einbauen kann. Zum anderen zeigt es, wie man Qt-Objekte mit Namen versehen kann, um sich dann beim Programmablauf mittels eigens dafür konzipierten Qt-Funktionen Debug-Informationen ausgeben zu lassen. Kapitel 22 stellt die drei unterschiedlichen Typen von Klassen vor, mit denen man leicht und portabel Netzwerkprogrammierung durchführen kann. Der erste Typ von Netzwerk-Klassen, der in diesem Kapitel vorgestellt wird, ist eher passiver Art. Zu dieser Art gehören unter anderem die beiden Klassen QUrl und QUrlOperator, mit denen man URLs (Uniform Resource Locator) protokollunabhängig bearbeiten kann. Danach stellt dieses Kapitel die Klasse QNetworkProtocol vor, die eine abstrakte Ebene zur Verfügung stellt, auf der man eigene Netzwerkprotokolle implementieren kann. Die Klasse QUrl- Operator ermöglicht dann ein Arbeiten mit solchen selbstdefinierten Netzwerkprotokollen. Im letzten Teil dieses Kapitels wird dann auf Klassen wie QSocket, QServerSocket, QDns, QFtp usw. eingegangen, die ein portables Arbeiten mit TCP/IP-Sockets ermöglichen. Kapitel 23 zeigt, wie man blockierungsfrei Daten im Hintergrund übertragen kann, denn das Schreiben in oder das Lesen aus Dateien kann bei großen Datenmengen eine sehr zeitaufwendige Operation sein, in der das ganze Programm blockiert ist, so dass der Benutzer in dieser Zeit nicht weiter mit der Applikation arbeiten kann. Qt bietet für solche Situationen abstrakte Klassen, die eine Übertragung von Daten im Hintergrund durchführen lassen. Diese Klassen werden in diesem Kapitel beschrieben. Kapitel 24 behandelt das XML-Modul von Qt, das einen XML-Parser mit einer SAX2- (Simple API for XML) Schnittstelle und eine Implementierung des DOM Level 1 (Document Object Model) zur Verfügung stellt. SAX2 ist eine sehr beliebte Java-Schnittstelle für XML-Parser, und DOM Level 1 ist eine W3C- Empfehlung für XML-Schnittstellen. Kapitel 25 stellt von der Vielzahl der zwischenzeitlich entwickelten Qt-Schnittstellen zu anderen Bibliotheken und Sprachen drei der wichtigsten kurz vor: OpenGL-Programmierung mit Qt, Perl-Programmierung mit Qt und Erstellen von Netscape-Plugins mit Qt. Kapitel 26 stellt den Qt GUI-Designer vor, der ein visuelles Design-Tool ist, das das Entwerfen und Implementieren grafischer Benutzerschnittstellen erheblich vereinfacht. Dieses Kapitel gibt anhand von Beispielen eine kurze Einführung in den bei Qt mitgelieferten Qt-Designer.

29 Einleitung Kapitel 27 stellt die im Rahmen des KDE-Projekts 1 entwickelte Entwicklungsumgebung KDevelop kurz vor. KDevelop erleichtert das Erstellen von GUI-Programmen ganz wesentlich und spart Zeit durch Automatisierung von Standard- Entwicklungsprozessen, genauso wie es einen direkten und transparenten Zugriff auf alle Informationen bietet, die man benötigt. Kapitel 28 beschreibt das von der Firma Trolltech bereitgestellte Tool tmake, mit dem man sich automatisch Makefiles aus seinen Qt-Quellprogrammen generieren lassen kann. Beispiel- und Übungsprogramme auf der CD Alle Programmbeispiele und Übungsprogramme dieses Buches befinden sich auf der in diesem Buch enthaltenen CD. Für Linux/Unix existiert auch ein eigener Browser, um alle Programmlistings interaktiv zu lesen bzw. diese Programme auch über diesen Browser zu starten; siehe dazu auch Abbildung 1. Um diesen Browser zu starten, müssen Sie nur in das Directory wechseln, in dem Sie die CD gemountet haben und dann qtbuch aufrufen. Noch ein kurzer Hinweis: Sollte Sie der tanzende Pinguin stören, bewegen Sie den Mauscursor auf ihn und warten Sie ein wenig, bis ein Tooltip eingeblendet wird. Das Lizenzmodell von Trolltech Trolltechs Lizenzmodell ist eigentlich relativ einfach, auch wenn es immer wieder für Verwirrung sorgt. In erster Linie ist Qt als kommerzielle Software erhältlich, derzeit für die drei Plattformen Unix/X11, MS-Windows und Linux/Embedded. An Unterstützung für weitere Plattformen z.b. Mac OS X wird gearbeitet. Als kommerzieller Lizenznehmer der Desktop-Verion von Qt erhalten Sie die Qt-Bibliothek mit vollständigem Quellcode eine persönliche Lizenz um kommerzielle Anwendungen mit Qt entwickeln zu können ein Jahr freie Upgrades auf alle neuen Versionen von Qt ein Jahr -Support die vollständige Referenz Dokumentation Es gibt keine Royalties, Run-Time-Lizenzen oder weitere Kosten, d. h. Sie können ohne weiteres Qt-basierte Anwendungen statisch oder dynamisch gelinked vertreiben. Derzeit werden zwei verschiedene Editionen angeboten: die Professional Edition und die Enterprise Edition 1 KDE ist die Abkürzung für K Desktop Environment (siehe auch 7

30 Einleitung Abbildung 1: Der Browser für die Beispiel- und Übungsprogramme (unter Linux/Unix) Unterschiede liegen im Umfang und Preis. Als Preisbeispiel kostet die Dual-Pack Enterprise Edition für 6 Entwickler für sowohl MS-Windows als auch Unix/X11 pro Entwickler USD (Stand Juni 2001). Im Preis enthalten sind ein Jahr Upgrades und technischen Support. Mit dieser Preisstruktur befindet sich Trolltech deutlich im unteren Preissegement bei C/cppMultiplattform-Lösungen, aber eben auch über dem gewöhnlichen Budget von Privatanwendern oder Studenten. Fuer Universitäten hat Trolltech deshalb das Qt Educational Program ins Leben gerufen, dass es ermöglicht, für Ausbildungszwecke kostenlose Site-Lizenzen für Qt zu erwerben. Privatleute haben die Möglichkeit, kostenlos die Qt NonCommercial Edition auszuprobieren und damit geschriebene Programme als freie Software zu vertreiben. Und last but not least: Für Benutzer Freier bzw. Open-Source Betriebsysteme wie Linux oder FreeBSD, die Freie bzw. Open-Source Software mit Qt schreiben wollen, gibt es die Qt Free Edition, die unter den Open-Source Lizenzen QPL und GNU GPL vertrieben wird. Freie bzw. Open-Source Software bedeutet nicht nur, dass diese Software in der Regel umsonst ist. Alle Anwender der Software müssen den 8

31 Einleitung komplette Quellcode umsonst bekommen können, einschliesslich des Rechts, die Software verändert oder unverändert weitervertreiben zu dürfen. Wichtig: Wenn Sie kommerzielle bzw. proprietäre Software mit Qt entwickeln auch unter Linux brauchen sie eine kommerzielle Qt Lizenz. Im Zweifelsfall fragen Sie am besten einfach 9

32 Einleitung 10

33 Kapitel 1 Einführung in die Objektorientierung und C++ Kunst ist die rechte Hand der Natur. Diese hat nur Geschöpfe, jene hat Menschen gemacht. F. Schiller Da Qt eine objektorientierte C -Klassenbibliothek ist, wird hier eine kurze Einführung in die Welt der Objektorientierung und insbesondere in die wichtigsten Konzepte der objektorientierten Sprache C gegeben. Leser, die mit der Objektorientierung und C vertraut sind, können dieses Kapitel übergehen und unmittelbar mit Kapitel 2 fortfahren. Zunächst zeigt dieses Kapitel, dass auch die Natur, in der wir leben, objektorientiert ist, bevor es die wesentlichen Aspekte vorstellt, welche die objektorientierte von der traditionellen (funktionalen) Softwareentwicklung unterscheiden. Da C eine Erweiterung der weitverbreiteten prozeduralen Sprache C ist, werden anschließend die Erweiterungen von C vorgestellt, die zwar sehr nützlich sind und ein eleganteres Programmieren in C zulassen, aber C noch nicht zu einer objektorientierten Sprache befähigen. Abschließend werden dann die wesentlichen neuen Sprachelemente vorgestellt, die C zu einer objektorientierten Sprache machen. 1.1 Objektorientierung in der realen Welt In der Welt, in der wir leben, sind wir von unzähligen Dingen (Objekten) mit verschiedenen Eigenschaften umgeben. Aufgrund dieser Eigenschaften sowie der Möglichkeiten, mit diesen Eigenschaften umzugehen oder von ihnen beeinflusst zu werden, kann man unterschiedliche Objekte zu Klassen zusammenfassen. Ein sehr schönes Beispiel hierfür liefert uns die Natur. Betrachten wir einen Ausschnitt aus der Welt der Lebewesen. Der Begriff Lebewesen beschreibt umfassend alle möglichen (uns bekannten) Lebensformen auf unserem Planeten. Dahinter verbergen sich jedoch verschiedene Gruppen. So unterscheidet man z. B. Pflanze und Tier. Diese Gruppen (Unter- 11

34 1 Einführung in die Objektorientierung und C++ A > A M A I A 2 B = A 6 EA H * = K * K A 5 K C A J EA H. EI? D A I? D = J A 0 = K I = J A 6 EC A H Abbildung 1.1: Einteilung von Lebewesen klassen) kann man aufgrund unterschiedlicher Eigenschaften wiederum unterteilen (Tier: Säugetier, Fisch etc.). Es sind dann weitere Differenzierungen möglich (Säugetier: Mensch, Katze etc.), wobei auch diese Spezialisierungen weitere Unterteilungen zulassen, wie in Abbildung 1.1 gezeigt ist. Ordnet man jedem dieser Kästen aus Abbildung 1.1 bestimmte Eigenschaften zu, so erkennt man, dass die Anzahl der Eigenschaften von oben nach unten zunimmt. Der obersten Klasse ( Lebewesen ) kann man nur die Eigenschaft lebendig zuordnen. Gehen wir eine Stufe tiefer und betrachten die Gruppe Tier, die wieder alle gewisse Eigenschaften wie z. B. bewegungsfähig gemeinsam haben, während die Gruppe Pflanzen andere Charakteristika aufweist. Entscheidend ist, dass beide Gruppen, sowohl Tiere als auch Pflanzen, die Eigenschaft lebendig von der ihr übergeordneten Klasse Lebewesen erben. Begeben wir uns noch weiter nach unten, so werden wir auf immer mehr (neue) Eigenschaften stoßen. Die Besonderheit liegt darin, dass eine Unterklasse sämtliche Eigenschaften der übergeordneten Klasse übernimmt (erbt). So ist letztendlich die genaue Beschreibung eines bestimmten Lebewesens möglich. Solange wir nur die Beschreibung eines bestimmten Lebewesens betrachten, sprechen wir also von Klasse. Nun gibt es aber von jeder möglichen untergeordneten Lebewesen-Klasse mehr oder weniger viele Vertreter (Exemplare). Hier sprechen wir dann von einem Objekt (auch als Instanz bezeichnet), das alle Eigenschaften der entsprechenden Klasse besitzt. So ist z. B. ein Tiger namens Saimura in einem bestimmten Zoo ein Objekt (eine Instanz) der Klasse Tiger, die von der Klasse Katze abgeleitet wurde, welche wiederum Säugetier als Basisklasse hat usw. Allgemein gilt also, dass die in der realen Welt vorkommenden Elemente immer spezifischere Eigenschaften aufweisen, je tiefer sie sich in einer entsprechenden 12

35 1.1 Objektorientierung in der realen Welt Abbildung 1.2: Objekte (Exemplare) zur Klasse Tiger Baumhierarchie (wie sie z. B. in Abbildung 1.1 gezeigt) befinden. Bei gleichartigen Objekten wird also nicht jedes einzelne Objekt für sich beschrieben, sondern es wird eine allgemeine Beschreibung (Klasse) für diesen Typ von Objekten gegeben. Mit Hilfe solcher Beschreibungen lassen sich dann die konkreten Objekte den jeweiligen Klassen zuordnen. Jedes individuelle Objekt ist dann ein Exemplar der entsprechenden Klasse (siehe auch Abbildung 1.2). Die Tiger Samurai, Taigon und Rufus in Abbildung 1.2 sind alle Exemplare (Instanzen, Objekte) der Klasse Tiger. Es ist offensichtlich, dass die Klasse Tiger kein eigenes Objekt ist, sondern eben nur eine Beschreibung. In den nachfolgenden Abbildungen werden Klassen und Objekte nach der Notation der Unified Modeling Language (UML) dargestellt, d. h. als Rechtecke. Zur Unterscheidung von Klassen und Objekten wird bei Objekten der Name unterstrichen: =IIA > A J Abbildung 1.3: Objekt und Klasse in der UML-Notation Wenn man die Objekt-Klassen-Beziehung (Exemplarbeziehung, Instanzbeziehung) darstellen möchte, wird zwischen einem Objekt und seiner Klasse ein gestrichelter Pfeil in Richtung der Klasse gezeichnet: E I J =? A B =IIA > A J Abbildung 1.4: Objekt-Klassen-Beziehung Im Falle des Tigers Samurai sagt man dann: Samurai ist ein Exemplar der Klasse Tiger oder Samurai ist eine Instanz der Klasse Tiger : 13

36 1 Einführung in die Objektorientierung und C++ E I J =? A B 6 EC A H 5 = K H = E Abbildung 1.5: Beispiel einer Objekt-Klassen-Beziehung Die Objektorientierte Programmierung (OOP) stützt sich auf diese Denkweise. Es besteht die Möglichkeit, Klassen zu definieren und ihre Eigenschaften an Unterklassen zu vererben, um letztendlich die genaue Beschreibung eines bestimmten Sachverhalts zu erreichen. Ausgehend von dieser nun erhaltenen Beschreibung, können Objekte (Instanzvariable) deklariert/definiert werden, die letztendlich eine greifbare Repräsentation der jeweiligen Beschreibung darstellen. 1.2 Objektorientierung in der Software In diesem Kapitel werden die wesentlichen Konzepte vorgestellt, welche die objektorientierte Softwareentwicklung von der traditionellen (funktionalen) Softwareentwicklung unterscheiden. Schritt 1: Zusammenfügen von Daten und Funktionen Der erste Schritt zur Übernahme der Objektorientierung in die Softwareentwicklung war, dass man Daten und Funktionen, die in der funktionalen Softwareentwicklung noch als getrennte Einheiten nebeneinander standen, zu einer Einheit zusammenfügte, wie dies Abbildung 1.6 verdeutlicht. Hierbei lag die Idee des Füge zusammen, was zusammengehört zugrunde. Man beseitigte damit einen ersten großen Nachteil von nicht objektorientierten Programmen, die keinen direkten Bezug zwischen Daten und den Funktionen, die auf diese Daten lesend oder schreibend zugriffen, direkt erkennen ließen. Wie leicht aus Abbildung 1.6 zu erkennen ist, verschmelzen bei der Objektorientierten Programmierung die Daten und die (diese Daten bearbeitenden) Funktionen zu einer Einheit, wodurch eine klare, eindeutige und überschaubare Softwarestruktur = I I EI? D A B K J E = A 5 B J M = H A A J M E? K C, = J A 8 = H E= > A N 8 = H E= > A O > A J H EA J EA H J A 5 B J M = H A A J M E? K C, = J A, = J A 8 = H E= > A = 8 = H E= > A 8 = H E= > A > 8 = H E= > A. K J E. K J E. K J E!. K J E N. K J E O. K J E 8 = H E= > A!. K J E E. K J E N Abbildung 1.6: Klassische und objektorientierte Programmierung 14

37 1.2 Objektorientierung in der Software = I I EI? D A B K J E = A 5 B J M = H A A J M E? K C > A J H EA J EA H J A 5 B J M = H A A J M E? K C, = J A 8 = H E= > A N 7 JH EA HJA H K C HEBB C E? D, = J A =? D = K A D E C A I? D J J 8 = H E= > A = 8 = H E= > A > 7 JH EA HJA H K C H EB E B? D J C E? D. K J E. H B K J E. K J E N. K J E O. K J E. H B K J E Abbildung 1.7: Zugriffsschutz bei der Objektorientierten Programmierung erreicht wird. Es lässt sich auf einen Blick erkennen, welche Daten durch welche Funktionen bearbeitet (verändert) werden. Schritt 2: Information Hiding Ein zweiter großer Nachteil der klassischen funktionalen Programmierung ist ihr mangelndes Schutzkonzept, da sie einen ungeschützten (meist auch ungewollten) Zugriff fremder Funktionen auf Daten zulässt. Um diesen Nachteil zu beseitigen, woraus oft schwer auffindbare Fehler resultierten, führte die Objektorientierung ihr eigenes Schutzkonzept ein, indem sie Möglichkeiten anbietet, Daten und Funktionen einer Klasse verschiedenen Schutzgraden (privat: nur innerhalb der Klasse ansprechbar; öffentlich: auch außerhalb der Klasse zugänglich) zuzuordnen. So können bei entsprechender Definition die Daten einer Klasse nur über die vom Programmierer zur Verfügung gestellten Funktionen verändert werden. Ein unkontrollierter Zugriff durch Fremdfunktionen wird somit verhindert. Abbildung 1.7 verdeutlicht diesen Sachverhalt. Diese Abbildung zeigt auch, dass ein Zugriff auf die geschützten Daten niemals direkt, sondern nur durch die nach außen sichtbaren Funktionen möglich ist. Schritt 3: Verwendung bereits vorhandener Software Wie bereits angesprochen, werden in der Objektorientierten Programmierung Objekte aufgrund vorliegender Klassendefinitionen gebildet. Somit besteht die Möglichkeit, Klassendefinitionen für oft benötigte Sachverhalte in so genannten Klassenbibliotheken zu hinterlegen. Durch einfaches Übernehmen dieser Definitionen (und eventuelles Hinzufügen neuer Teile mit Hilfe des Vererbungsmechanismus) wird die Softwareentwicklung stark vereinfacht. Man spricht auch von Softwareentwicklung durch Reproduktion (Nachbildung) von Objektbeschreibungen (Klassendefinitionen). 15

38 1 Einführung in die Objektorientierung und C Nicht-objektorientierte Erweiterungen in C++ Da C eine Erweiterung der weitverbreiteten prozeduralen Sprache C ist, werden hier zunächst die Erweiterungen von C vorgestellt Zeilen-Kommentare mit // Neben dem C-Kommentar, der innerhalb des Codes mit der Zeichenfolge /* eingeleitet und mit der Zeichenfolge */ beendet wird, bietet C zusätzlich noch die Zeichenfolge // zum Kommentieren an: Alle Zeichen ab // bis zum Zeilenende werden als Kommentar interpretiert. double epsilon; /* C-Kommentar, der sich über meherere Zeilen erstrecken kann und auch in C++ weiterhin verwendet werden kann. */ double epsilon; // Ab hier bis Zeilenende Kommentar (nur in C++ mögl.) Variablen-Deklarationen (auch im Anweisungsteil) In C war es vorgeschrieben, dass Variable nur entweder global oder am Anfang eines durch { gekennzeichneten Blockes deklariert werden durften. Variablen- Deklarationen an beliebigen Stellen innerhalb des Anweisungsteils waren nicht erlaubt. In C können nun Variablen-Deklarationen an jeder beliebigen Stelle im Code erfolgen. Die Lebensdauer der deklarierten Variablen beschränkt sich dabei (wie auch in C) auf den Block, in dem sie deklariert wurden: void function() {... //... printf("c-anweisungen"); // beliebige C/C++-Anweisungen... //... int z = 5; // Deklaration der Variablen z // Diese Variable ist nur innerhalb der... // Funktion function() bekannt int main(void) {... //... printf ("C-Anweisungen"); // beliebige C/C++-Anweisung... //... for (int i = 1; i < 10; i++) { // Deklaration der Variablen i... // Diese Variable ist innerhalb // der Funktion main bekannt return 0; 16

39 1.3 Nicht-objektorientierte Erweiterungen in C Default-Argumente bei Funktionsaufrufen Es gibt Anwendungsfälle, bei denen nicht alle bei einer Funktionsdeklaration angegebenen Parameter bei jedem Aufruf wirklich benötigt werden. In solchen Fällen muss man in C beim Aufruf trotzdem für jeden Parameter ein entsprechendes Argument (Dummy-Argument) angeben. Nehmen wir z. B. eine Funktion add_- bis4(), die bis zu vier ganze Zahlen (als Argumente anzugeben) addieren kann und das Ergebnis zurückgibt. int add_bis4(int z1, int z2, int z3, int z4) { return(z1+z2+z3+z4); Will man in C nun nur zwei Zahlen durch diese Funktion addieren lassen, muss man trotzdem alle vier Argumente angeben: ergeb = add_bis4(25, 43, 0, 0); /* in C: Dummy-Argumente 0, 0 */ C bietet nun für solche Fälle so genannte Default-Argumente an, die man den Parametern bei der Deklaration/Implementierung einer Funktion zuweisen kann, wie z. B.: int add_bis4(int z1, int z2=0, int z3=0, int z4=0) { return(z1+z2+z3+z4); Gibt der Aufrufer der Funktion das jeweilige Default-Argument nicht an, so wird dieses Argument automatisch mit seinem Default-Wert belegt: ergeb = add_bis4(25, 43); // entspr.: ergeb = add_bis4(25, 43, 0, 0); ergeb = add_bis4(7, 4, -8); // entspr.: ergeb = add_bis4(7, 4, -8, 0); ergeb = add_bis4(53); // entspr.: ergeb = add_bis4(53, 0, 0, 0); Default-Argumente werden oft auch dazu verwendet, um für eine Funktion ein bestimmtes Standardverhalten vorzugeben. Werden beim Aufruf dieser Funktion keine Argumente für die optionalen Default-Argumente angegeben, so verhält sich die Funktion entsprechend ihrem festgelegten Standard. Möchte der Aufrufer aber die Funktion abweichend von ihrer Standardvorgabe ausführen lassen, kann er dies über die Angabe eigener Argumente (für die Default-Argumente) steuern. Nachfolgend ist hierzu ein Beispiel gegeben. void kostrech(double einnahme, double ausgabe, char *waehrung="eur", double factor=1.0) { double gewinn = einnahme - ausgabe; printf("einnahme: %.2f %s (%.2f EUR)\n", einnahme, waehrung, einnahme*factor); printf("ausgabe : %.2f %s (%.2f EUR)\n", ausgabe, waehrung, ausgabe*factor); printf(" \n"); printf("gewinn : %.2f %s (%.2f EUR)\n", gewinn, waehrung, gewinn*factor); Für diese Funktion sind nun z. B. folgende Aufrufe möglich: 17

40 1 Einführung in die Objektorientierung und C++ kostrech( , ); // Standardverhalten // Ausgabe bei diesem Aufruf: Einnahme: EUR ( EUR) // Ausgabe : EUR ( EUR) // // Gewinn : EUR ( EUR) kostrech(1800.0, , "YEN", ); // Ausgabe bei diesem Aufruf: Einnahme: YEN (17.10 EUR) // Ausgabe : YEN (23.75 EUR) // // Gewinn : YEN (-6.65 EUR) kostrech( , , "USD", 1.02); // Ausgabe bei diesem Aufruf: Einnahme: USD ( EUR) // Ausgabe : USD ( EUR) // // Gewinn : USD ( EUR) Es ist zu beachten, dass Default-Argumente immer nur für die hinteren (am weitesten rechts stehenden) Parameter innerhalb der Schnittstelle erlaubt sind. Würde beim Aufruf einer Funktion mit Default-Argumenten ein mittleres Argument weggelassen werden, wäre es dem Compiler nicht möglich herauszufinden, welcher Parameter entfallen ist. Demzufolge könnte er auch die nachfolgenden Argumente nicht richtig zuordnen. Dazu folgendes Beispiel: void f1(int a, int b, int c = 0); void f2(int a, int b = 0, int c = 0); void f3(int a, int b = 0, int c); // erlaubt // erlaubt // NICHT erlaubt Im Folgenden sind alle möglichen Aufrufformen dieser hier deklarierten Funktionen gezeigt: f1( 1, 2, 3); // Alle Argumente angegeben f1( 1, 2); // 3. Default-Argument weggelassen f2( 4, 5, 6); // Alle Argumente angegeben f2( 4, 5); // 3. Default-Argument weggelassen f2( 4); // 2. Und 3. Default-Argument weggelassen // f3() - Aufruf nicht möglich, da Definition syntaktisch falsch Default-Argumente dürfen nur im Prototyp, nicht aber bei der Definition einer Funktion angegeben werden Überladen von Funktionen Es besteht oft der Wunsch, für ähnliche, aber doch unterschiedliche Aufgaben Funktionsaufrufe mit gleichem Namen verwenden zu können. Anwendungsfälle und mögliche Lösungen hierfür wurden bereits im vorigen Kapitel vorgestellt. Es gibt aber auch Anforderungen, die sich durch Default-Argumente nicht lösen lassen. Zum Beispiel könnte man eine Funktion add() benötigen, die Variablenwerte un- 18

41 1.3 Nicht-objektorientierte Erweiterungen in C++ terschiedlichen Datentyps addiert. In C waren hierfür immer Funktionen mit verschiedenen Namen notwendig: void add_i(int i1, int i2); void add_d(double d1, double d2); void add_il(int i1, int i2, long l1);... // Addiert zwei Integers // Addiert zwei Doubles // Addiert zwei Integers und ein long C bietet nun die Möglichkeit, mehrere Funktionen mit gleichem Namen, aber unterschiedlichen Schnittstellen zu implementieren. Man spricht dabei vom Überladen (Overloading) von Funktionen. Die Entscheidung, welche Funktion bei einem Aufruf ausgeführt wird, ist abhängig von der Anzahl und vom Datentyp der Argumente, da C intern zur Benennung einer Funktion nicht nur deren Namen, sondern auch die Anzahl und die Typen der Parameter verwendet. Programm 1.1 ist ein Beispiel zum Überladen von Funktionen, indem es die Funktion hoch() zum Berechnen von x y in drei Varianten anbietet. Programm 1.1 overload.cpp: Überladen einer Funktion zur Berechnung von x y #include <stdio.h> #include <math.h> long hoch(int y, int x) { return (long)pow(x, y); long hoch(int y) { return (long)pow(10, y); double hoch(int y, double x) { return pow(x, y); int main(void) { printf(" 3^4 = %ld\n", hoch(4, 3)); printf(" 10^5 = %ld\n", hoch(5)); printf("2.3^4 = %f\n", hoch(4, 2.3)); return 0; Je nachdem, ob die Funktion hoch() mit zwei int-argumenten, einem int-argument oder aber einem int- und einem double-argument aufgerufen wird, wird die entsprechende Funktion aufgerufen, so dass sich die folgende Ausgabe für das Programm 1.1 ergibt: 3^4 = 81 10^5 = ^4 = Inline-Funktionen Da jeder Funktionsaufruf mit einer Laufzeiterhöhung (aufgrund des erforderlichen Stackmanagements) verbunden ist, wurden in C bei zeitkritischen Aufgabenstellungen oft Makros anstelle von Funktionen verwendet. Jeder Makroaufruf wurde dann vom Präprozessor (Precompiler) durch die entsprechenden Anweisungen direkt im Code ersetzt. Die Verwendung von Makros ist jedoch ziemlich aufwendig und fehleranfällig, da bei einem Makroaufruf nur eine (etwas bessere) Ersetzung 19

42 1 Einführung in die Objektorientierung und C++ von Text stattfindet, was viele Nebeneffekte auslösen kann, wie beispielsweise die mehrmalige Auswertung der Argumente. C bietet nun die Möglichkeit, so genannte inline-funktionen zu definieren, um die Vorteile von Makros (schnellere Ausführung, da Code der entsprechenden inline-funktion an der Aufrufstelle eingefügt wird und somit das Stackmanagement entfällt) mit den Vorteilen von Funktionen (Auswertung der Argumente vor dem Funktionsaufruf) zu kombinieren. Die Deklaration von inline-funktionen entspricht der normaler Funktionen, nur dass das Schlüsselwort inline am Beginn der Funktionsdeklaration angegeben wird. Programm 1.2 zeigt typische Seiteneffekte, die bei Makros, nicht aber bei inline-funktionen auftreten können. Programm 1.2 inline.cpp: Seiteneffekte von Makros, die bei inline-funktionen nicht auftreten #include <stdio.h> #define quad_makro(zahl) zahl * zahl inline int quad_inline(int zahl) { return zahl*zahl; int main(void) { int z; z = 3; printf("quad_makro(++z) = %d\n", quad_makro(++z) ); z = 3; // quad_makro(++z) wird zu: ++z * ++z --> 4*5 printf("quad_inline(++z) = %d\n", quad_inline(++z) ); // quad_inline(++z) wird zu: quad_line(4) --> 4*4 return(0); Programm 1.2 würde folgendes ausgeben: quad_makro(++z) = 20 quad_inline(++z) = 16 Da die Anweisungen von inline-funktionen sowie auch die von Makros direkt im Code eingefügt werden, sollten beide nur für kleine Aufgaben eingesetzt werden, da dies sonst bei häufigen Aufrufen zu einer Codeaufblähung führt Referenzen/Referenz-Operator Zugriffsmöglichkeiten in C In C existieren prinzipiell zwei Arten des Zugriffs auf ein im Hauptspeicher (RAM) liegendes Datum (aus Sicht des C-Programmierers). Zum Verständnis werden beide hier noch einmal kurz vorgestellt: 1. Zugriff auf ein Datum direkt über eine Variable (einen Variablennamen) int a; // Variable vom Typ Integer int b = 7; // Variable vom Typ Integer mit Initialisierung 20

43 1.3 Nicht-objektorientierte Erweiterungen in C++ a = b; // Zuweisung des Wertes einer Variablen an eine andere (1) b = 4; // Zuweisung eines Wertes an eine Variable (2) Dieser Code bewirkt den in Abbildung 1.8 gezeigten Sachverhalt. = > % = > % % = > % " Abbildung 1.8: Zugriff auf ein Datum über eine Variable 2. Zugriff auf ein Datum über einen Zeiger, der auf das Datum zeigt int a; // Variable vom Typ Integer int b = 7; // Variable vom Typ Integer mit Initialisierung int* zgr; // Zeiger auf ein Datum vom Typ Integer zgr = &a; // Zeiger erhält die Adresse einer Variablen (1) *zgr = b; // Wertzuweisung an die vom Zeiger adressierte Variable (2) Dieser Code bewirkt den in Abbildung 1.9 gezeigten Sachverhalt. = > CH % = > % CH = = % > % CH = Abbildung 1.9: Zugriff auf ein Datum über einen Zeiger Zugriff auf ein Datum über eine Referenz in C++ Eine Referenz in C kann man sich als zweiten Namen oder als Alias einer Variablen, also eines beliebigen Speicherbereiches, vorstellen. Diesen Alias kann man in der gleichen Art und Weise verwenden wie die referenzierte Variable. Der folgende C -Auszug zeigt eine Möglichkeit der Verwendung einer Referenz: int a; // Variable vom Typ Integer int b = 7; // Variable vom Typ Integer mit Initialisierung int& ref = a; // Referenz auf eine Variable vom Typ Integer ref = 4; // Wertzuweisung an Variable a über Variable ref Dieser Code bewirkt den in Abbildung 1.10 gezeigten Sachverhalt., EA I A H 5 F A E? D A H F = J = > A H M A E = A A H H A B = C A I F H? D A M A A HA B = > HA B = % > " % Abbildung 1.10: Zugriff auf ein Datum über eine Referenz 21

44 Kapitel 2 Allgemeines zu Qt Non quia difficilia sunt non audemus, sed quia non audemus difficilia sunt. (Nicht weil es schwer ist, wagen wir es nicht, sondern weil wir es nicht wagen, ist es schwer.) Seneca Dieses Kapitel klärt zunächst einmal, was Qt überhaupt ist und welche Vorteile Qt gegenüber anderen GUI-Produkten 1 besitzt, bevor der wichtige Qt-Begriff Widget eingeführt wird. Die nächsten Absätze gehen dann kurz auf die bei Qt mitgelieferte Dokumentation ein, bevor abschließend auf die Generierung von Qt-Programmen mit make sowie mit dem eigens von den Qt-Entwicklern angebotenen Tool tmake zur automatischen Erstellung von Makefiles eingegangen wird. 2.1 Was ist Qt und warum Qt? Qt ist eine einfache und portable C++-Klassenbibliothek zur GUI-Programmierung Qt ist eine von der norwegischen Firma Troll Tech entwickelte C++-Klassenbibliothek, die eine einfache und portable GUI-Programmierung ermöglicht. Manche Programmierer behaupten sogar, dass Qt die einfachste GUI-Programmierung überhaupt unter den vielen angebotenen GUI-Toolkits erlaubt. Daneben sind mit Qt entwickelte Programme sowohl unter allen Linux/Unix- wie allen Windows-Systemen lauffähig. Qt ist ein GUI-Toolkit GUI-Toolkits sind in der MS-Windows-Welt kaum bekannt, dafür aber um so mehr in der Unix-Welt. Der Grund hierfür ist, dass die Windows-GUI-Schnittstelle API schon von sich aus eine high-level-schnittstelle ist, die z. B. Buttons, Laufbalken oder Funktionen zum Ändern von Farben und Fonts anbietet. 1 GUI steht für Graphical User Interface. 115

45 2 Allgemeines zu Qt Anders verhält sich dagegen die unter Unix angebotene Schnittstelle des X Window System, die zwar sehr flexibel ist, aber nur low-level-funktionen anbietet, wie z. B. zum Zeichnen primitiver Graphiken (Linien, Rechtecke usw.) oder zum Setzen der Hinter- und Vordergrundfarbe. Diese X-Window-Schnittstelle bietet keine high-level-funktionen zum Erzeugen von Buttons, Laufbalken, Dialogboxen usw. Dies ist der Grund, warum einige Toolkits entwickelt wurden, um die GUI- Programmierung unter Unix zu vereinfachen. Der bekannteste Toolkit dürfte Motif sein, was nicht nur ein Toolkit, sondern auch eine Spezifikation für ein bestimmtes look-and-feel ist. Allerdings ist die Verwendung von Motif sehr schwierig und äußerst mühsam, was sich daran erkennen lässt, dass Motif-Programme wesentlich länger sind als Qt-Programme, die das gleiche leisten. Nichtsdestotrotz ist Motif ein Standard. Qt ist nun ein GUI-Toolkit, der dieses look-and-feel von Motif mit einer wesentlich einfacheren GUI-Programmierschnittstelle zur Verfügung stellt. Nun noch einmal zurück zum Windows-API, das Funktionen anbietet, um GUI- Elemente (wie Buttons, Menüs usw.) zu erzeugen, Farben zu ändern usw. Diese API-Schnittstelle ist zwar wesentlich einfacher als das direkte Programmieren des X Window System, aber sie ist immer noch nicht benutzerfreundlich genug. Daneben existiert noch die Microsoft Foundation Class (MFC), welche zwar highlevel-funktionen anbietet, aber doch sehr komplex in ihrer Verwendung ist. Bei der Benutzung von MFC muss der Benutzer immer noch sehr viel Zeit aufwenden, um eine Bedienoberfläche zu erzeugen, statt sich auf den eigentlichen Kern seiner Aufgabe zu konzentrieren. Qt ist nun ein so genanntes application framework, das alle die eben erwähnten Nachteile vermeidet. Unter einem Framework versteht man ein komplettes Programmiersystem, das dem Programmierer die low-level-arbeiten abnimmt. Dazu stellt es ihm eine Bibliothek von Klassen zur Verfügung, so dass er sich Objekte definieren kann, die genau ein user-interface-element repäsentieren (wie z. B. einen Button oder ein Menü), und er so über die vom Programmiersystem bereitgestellten Konstrukte alle Anwenderinteraktionen mit diesen Elementen verwalten kann. Vorteile von Qt Für die Verwendung von Qt bei der Entwicklung neuer Software sprechen die folgenden Vorzüge: Qt ist für Unix-Systeme (wie Linux, FreeBSD oder Solaris) frei, wenn man freie Software für diese Systeme schreibt. Qt ist portabel und einfach. Programme, die mit Qt geschrieben werden, sind sowohl unter Linux/Unix als auch unter Windows lauffähig, was z. B. für MFC nicht gilt, denn mit MFC entwickelte Programme sind nur unter Windows- Systemen lauffähig. Zudem stufen viele Programmierer, die sowohl mit MFC als auch mit Qt gearbeitet haben, Qt als einfacher ein. Qt ist schnell. Programme, die mit Qt geschrieben sind, laufen sehr schnell ab. 116

46 2.2 Der Begriff Widget 2.2 Der Begriff Widget Qt arbeitet mit so genannten Widgets. Dieser Begriff wird unter Unix für Windows (Fenster) verwendet: Widget ist eine Wortschöpfung aus den beiden Begriffen Window und Gadget (entspricht Controls unter Windows-Betriebssystemen). Nahezu alles, was man auf einer in Qt geschriebenen Oberfläche sieht, ist ein Widget: Buttons, Laufbalken, Dialogboxen usw. Widgets können ihrerseits wieder Subwidgets enthalten, wie z. B. Buttons oder Texteingabefelder in einer Dialogbox. In Qt ist ein Widget ein Objekt einer Klasse, die von der Klasse QWidget abgeleitet ist. Qt enthält viele vordefinierte Widgets, allerdings kann der Qt-Programmierer auch seine eigenen Widgets definieren. 2.3 Die Qt-Online-Dokumentation im HTML-Format Qt bietet eine hervorragende Online-Dokumentation im HTML-Format an. Deswegen ist es in dieser Qt-Einführung auch nicht notwendig, eine Qt-Referenz anzugeben, da mit jeder Qt-Distribution eine vollständige Online-Qt-Referenz mitgeliefert wird. Um diese Online-Dokumentation zu lesen, muss ein Web-Browser wie z. B. Netscape Navigator verwendet werden. Andere Browser, wie z. B. arena oder lynx unter Linux sind auch möglich, da die Qt-Online-Dokumentation weder spezielle HTML-Konstrukte verwendet noch Java oder JavaScript voraussetzt. Abbildung 2.1: Startseite der Qt-Referenz-Dokumentation 117

47 2 Allgemeines zu Qt Im Browser ist dann zuerst die Datei index.html im Verzeichnis doc der entsprechenden Qt-Installation zu öffnen (unter Linux/Unix-Systemen meist: /usr/lib/qt/doc/html bzw. /usr/lib/qt2/doc/html) um die Titelseite der Qt-Dokumentation einzublenden (siehe auch Abbildung 2.1). Um einen Eindruck zu bekommen, wie der Qt-Klassenbaum organisiert ist, sollte man zunächst den Punkt Annotated Class List anklicken. Man bekommt dann eine Liste aller Qt-Klassen, die public sind, mit einer einzeiligen Kurzbeschreibung angezeigt. Später, nachdem man mit Qt etwas mehr vertraut ist, kann man dann meist direkt von der Startseite zum Punkt Alphabetical Class List wechseln. Die dann eingeblendete Liste enthält keine Kurzbeschreibung und zeigt mehr Klassen auf einer Seite. Um einen ersten Eindruck über die Beschreibung der einzelnen Klassen zu bekommen, kann man z. B. auf den Link QButton klicken. QButton ist die Klasse, die für die Erzeugung von Buttons und deren Interaktionen mit dem Programm zuständig ist (siehe auch Abbildung 2.2). In Abbildung 2.2 sieht man als erste Zeile eine Kurzbeschreibung der jeweiligen Klasse. In der zweiten Zeile ist dann der Name der Headerdatei angegeben, in der diese Klasse definiert ist. Es folgt der Name der Basisklasse, von der diese Klasse abgeleitet ist, bevor in der nächsten Zeile eine Liste der Klassen angegeben ist, die wiederum von dieser Klasse (hier QButton) abgeleitet sind, was in Abbildung 2.2 die Klassen QCheckBox, QPushButton, QRadioButton und QToolButton sind. Der Link List of all member functions ist wichtig für den Fall, dass man einen Überblick über alle Memberfunktionen haben möchte, also nicht nur die Memberfunk- Abbildung 2.2: Die Referenz-Dokumentation für QButton 118

48 2.4 Die Qt-Dokumentation als Postscript-Datei tionen, die in der Klasse selbst definiert sind, sondern auch über die, welche diese Klasse von ihren übergeordneten Klassen erbt. Anschließend folgt eine Liste aller Public Members, die direkt in dieser Klasse definiert sind, sowie etwaige Listen von Public Slots, Signals oder Protected Members, die diese Klasse anbietet. Nach diesen Listen wird eine detaillierte Beschreibung der entsprechenden Klasse gegeben, die oft ganze Beispiele enthält, wie diese Klasse zu verwenden ist. 2.4 Die Qt-Dokumentation als Postscript-Datei Die Qt-Herstellerfirma Troll Tech bietet eine sehr gute Qt-Dokumentation als Postscript-Dateien auf ihrem Webserver zum Herunterladen an. 2.5 Kompilieren von Qt-Programmen Um Qt-Programme zu kompilieren, existieren zwei Möglichkeiten: die direkte Eingabe der Kommandozeile, was mit der Zeit sehr mühsam ist, oder aber das Arbeiten mit Makefiles. Direkte Eingabe der Kommandozeile Hier wird nur exemplarisch die Programmgenerierung für den Compiler Visual C++ (auf Windows-Betriebssystemen) und den Compiler GNU C++ (auf Unix-Systemen) vorgestellt. Daneben existieren weitere Möglichkeiten der Programmgenerierung, wie z. B. für den Compiler Borland C++ (auf Windows-Betriebssystemen) und für nahezu alle in der Unix-Welt bekannten Compiler. Diese werden hier nicht alle vorgestellt. Jedoch entspricht die Programmgenerierung auch auf für diese Compiler im Wesentlichen der hier vorgestellten Vorgehensweise. Arbeitet man mit dem Microsoft Visual-C++-Compiler unter einem Windows-Betriebssystem, muss man die beiden folgenden Kommandozeilen eingeben, wenn Qt im Directory c:òqt installiert wurde. cl -c -nologo -W3 -O1 -DNO_DEBUG -I"C:\qt\include" -Fo prog.obj prog.cpp link /NOLOGO /SUBSYSTEM:windows /OUT:myprog.exe myprog.obj C:\qt\lib\qt.lib user32.lib gdi32.lib comdlg32.lib imm32.lib ole32.lib uuid.lib wsock32.lib Auf Unix-Systemen sollte zunächst die Environmentvariable QTDIR gesetzt werden (z. B. export QTDIR=/usr/lib/qt oder export QTDIR=/usr/lib/qt2). Um dann ein Qt-Programm zu kompilieren, muss die folgende Kommandozeile eingegeben werden: c++ -I$QTDIR/include -L$QTDIR/lib -lqt -o prog prog.cpp 119

49 2 Allgemeines zu Qt Abhängig vom jeweiligen Unix-System kann diese Kommandozeile auch etwas anders aussehen. Die obige Kommandozeile gilt jedenfalls für alle Systeme, die den GNU C++-Compiler verwenden. Arbeiten mit Makefiles In diesem Fall ist das von Firma Troll Tech zur Verfügung gestellte Tool tmake sehr hilfreich. Für tmake muss man nur eine entsprechende.pro-datei erstellen, wie z. B. die folgende Datei myprog.pro: TEMPLATE = app CONFIG HEADERS SOURCES unix:libs= -lm TARGET = qt warn_on release = cannon.h gamebrd.h lcdrange.h = cannon.cpp gamebrd.cpp lcdrange.cpp main.cpp = myprog Um sich nun das entsprechende Makefile 2 erstellen zu lassen, muss man dann nur noch folgendes aufrufen unter Windows-Betriebssystemen: tmake myprog.pro -o Makefile -win32 unter Linux/Unix-Betriebssystemen: tmake myprog.pro -o Makefile -unix Das von tmake erzeugte Makefile hat z. B. für Windows-Betriebssysteme, unter denen mit Visual-C++ gearbeitet wird, folgendes Aussehen (aus Platzgründen etwas komprimiert): ####### Compiler, tools and options CC = cl CXX = cl CFLAGS = -nologo -W3 -O1 -DNO_DEBUG CXXFLAGS= -nologo -W3 -O1 -DNO_DEBUG INCPATH = -I"$(QTDIR)\include" LINK = link LFLAGS = /NOLOGO /SUBSYSTEM:windows LIBS = $(QTDIR)\lib\qt.lib user32.lib gdi32.lib comdlg32.lib imm32.lib ole32.lib uuid.lib wsock32.lib MOC = moc ZIP = zip -r -9 ####### Files HEADERS = cannon.h gamebrd.h lcdrange.h SOURCES = cannon.cpp gamebrd.cpp lcdrange.cpp main.cpp OBJECTS = cannon.obj gamebrd.obj lcdrange.obj main.obj SRCMOC = moc_cannon.cpp moc_gamebrd.cpp moc_lcdrange.cpp OBJMOC = moc_cannon.obj moc_gamebrd.obj moc_lcdrange.obj DIST = TARGET = myprog.exe 2 Das Tool make und die Syntax von Makefiles ist im Buch Linux-Unix Profitools von Helmut Herold (Addison-Wesley) detailliert beschrieben. 120

50 2.5 Kompilieren von Qt-Programmen ####### Implicit rules.suffixes:.cpp.cxx.cc.c.cpp.obj: $(CXX) -c $(CXXFLAGS) $(INCPATH) $<.cxx.obj: $(CXX) -c $(CXXFLAGS) $(INCPATH) $<.cc.obj: $(CXX) -c $(CXXFLAGS) $(INCPATH) $<.c.obj: $(CC) -c $(CFLAGS) $(INCPATH) $< ####### Build rules all: $(TARGET) $(TARGET): $(OBJECTS) $(OBJMOC) $(LINK) $(LFLAGS) /OUT:$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) moc: $(SRCMOC) tmake: Makefile Makefile: myprog.pro tmake myprog.pro -o Makefile dist: $(ZIP) myprog.zip myprog.pro $(SOURCES) $(HEADERS) $(DIST) clean: -del cannon.obj -del gamebrd.obj -del lcdrange.obj -del main.obj -del moc_cannon.cpp -del moc_gamebrd.cpp -del moc_lcdrange.cpp -del moc_cannon.obj -del moc_gamebrd.obj -del moc_lcdrange.obj -del $(TARGET) ####### Compile cannon.obj: cannon.cpp cannon.h gamebrd.obj: gamebrd.cpp gamebrd.h lcdrange.h cannon.h lcdrange.obj: lcdrange.cpp lcdrange.h main.obj: main.cpp gamebrd.h lcdrange.h cannon.h moc_cannon.obj: moc_cannon.cpp cannon.h moc_gamebrd.obj: moc_gamebrd.cpp gamebrd.h lcdrange.h cannon.h moc_lcdrange.obj: moc_lcdrange.cpp lcdrange.h moc_cannon.cpp: cannon.h $(MOC) cannon.h -o moc_cannon.cpp moc_gamebrd.cpp: gamebrd.h $(MOC) gamebrd.h -o moc_gamebrd.cpp moc_lcdrange.cpp: lcdrange.h $(MOC) lcdrange.h -o moc_lcdrange.cpp 121

51 2 Allgemeines zu Qt Nachdem dieses Makefile automatisch erstellt wurde, muss man unter Windows- Systemen nur noch nmake aufrufen, um ein ausführbares Programm zu generieren. Die von tmake unter Linux/Unix-Systemen erzeugten Makefiles sehen weitgehend ähnlich aus, nur dass sie z. B. andere Pfadnamen für die Headerdateien und Bibliotheken sowie eventuell auch andere Makronamen im Makefile enthalten. Unter Linux/Unix muss man dann make aufrufen, um ein ausführbares Programm zu generieren. 122

52 Kapitel 6 Vordefinierte Dialogfenster Genau betrachtet, ist alles Gespräch nur Selbstgespräch. C. Morgenstern Ein Dialogfenster ist ein Widget, das für eine spezielle Kommunikation mit dem Benutzer ausgelegt ist, wie z. B. Auswahl einer bestimmten Farbe oder einer Datei. Qt bietet für solche typischen Kommunikationen mit dem Benutzer eine ganze Reihe von vordefinierten Dialogfenstern an, die schon mit entsprechenden Auswahlmöglichkeiten und/oder Buttons versehen sind und so dem Qt-Programmierer eine Menge Arbeit abnehmen. Die wichtigsten von Qt vordefinierten Dialogfenster sind: QDialog: Basisklasse für vordefinierte Dialogfenster QColorDialog: zur Auswahl einer Farbe QFileDialog: zur Auswahl einer Datei (z. B. zum Öffnen oder Speichern) QFontDialog: zur Auswahl eines Font (Zeichensatzes) QMessageBox: zur Anzeige von kurzen Informationen, die der Benutzer durch Drücken der dazu angebotenen Buttons bestätigen muss. QTabDialog: zur Stapelung von Widgets im Karteikartenformat, von denen über eine Karteikartenreiterleiste (Tableiste) immer eines in den Vordergrund gebracht werden kann. QWizard: zum Blättern in einer vorgegebenen Menge von Widgets. Dabei kann immer nur eine Seite vor- bzw. zurückgeblättert werden. Es wird dabei immer nur die aktuelle Seite angezeigt, während die anderen Seiten nicht sichtbar sind. QPrinter: zum Drucken mit möglichen Druckereinstellungen QInputDialog: für einfache Eingaben, wie z. B. Zahlen, Text oder Auswahl aus einer vorgegebenen Liste QProgressDialog: zur Anzeige in Form eines Prozentbalkens, wie weit eine bestimmte Aktion schon fortgeschritten ist 417

53 6 Vordefinierte Dialogfenster 6.1 Die Basisklasse QDialog Zunächst soll hier der Begriff modal geklärt werden, denn jedes Dialogfenster kann entweder modal oder nicht-modal sein: Ein nicht-modaler Dialog ist ein normales Window, das, während es eingeblendet ist, ein gleichzeitiges Arbeiten in anderen Windows dieses Programms zulässt. Ein modaler Dialog dagegen ist ein Window, das kein gleichzeitiges Arbeiten mit anderen Windows zulässt, während es eingeblendet ist. Erst nach der Beendigung eines modalen Dialogfensters ist es dem Benutzer wieder erlaubt, Aktivitäten in anderen Windows dieses Programms durchzuführen. Konstruktor und Methoden der Basisklasse QDialog Die Klasse QDialog bietet einen Konstruktor an: QDialog(QWidget *parent=0, const char *name=0, bool modal=false, WFlags f=0) Der Parameter modal legt dabei fest, ob es sich um einen modalen oder nichtmodalen Dialog handelt. Die Klasse QDialog bietet den folgenden enum-datentyp, der für das Resultat eines modalen Dialogs vorgesehen ist: enum DialogCode { Rejected, Accepted ; Wichtige Methoden, die die Klasse QDialog anbietet, sind: int exec(): startet den entsprechenden Dialog und liefert die Antwort des Benutzers auf diesen Dialog als Rückgabewert. Der Aufruf von exec() ist identisch mit einem Aufruf show(), gefolgt von einem result()-aufruf. Während diese Funktion für modale Dialoge sehr nützlich ist, macht sie keinen Sinn für nicht-modale Dialoge. Der Rückgabewert von exec() zeigt an, wie der Dialog beendet wurde: QDialog::Accepted (Button OK wurde gedrückt) bzw. QDialog::Rejected (Button Cancel wurde gedrückt). int result() const: liefert das Resultat des Dialogs als Rückgabewert. Wie exec() macht auch diese Methode nur Sinn bei modalen Dialogen. setresult(int) protected: setzt das Resultat des Dialogs auf Wert r. Die Klasse QDialog bietet unter anderem die folgenden Slotroutinen an: accept() virtual protected slot: schließt den Dialog und setzt das Resultat auf den Wert Accepted; entspricht dem Aufruf done(accepted). reject() virtual protected slot: schließt den Dialog und setzt das Resultat auf den Wert Rejected; entspricht dem Aufruf done(rejected). done(int r) virtual protected slot: schließt den Dialog und setzt das Resultat auf den Wert r; entspricht dem Aufruf hide(), gefolgt von setresult(r). Beispiel: Einblenden eines modalen oder nicht-modalen Dialogfensters Programm 6.1 ermöglicht es dem Benutzer, sich ein modales oder ein nicht-modales Dialogfenster anzeigen zu lassen. Die Voreinstellung ist das Einblenden eines nicht- 418

54 6.1 Die Basisklasse QDialog Abbildung 6.1: Modales Dialogfenster von Programm 6.1 mit Anzeige der Benutzerwahl (rechts) modalen Dialogfensters. Wird beim Aufruf dieses Programms die Option -m angegeben, wird ein modales Dialogfenster eingeblendet, wie es im linken Teil der Abbildung 6.1 gezeigt ist. Nachdem der Benutzer einen der beiden Buttons angeklickt hat, wie z. B. den OK-Button, wird ihm in einem Nachrichtenfenster (Messagebox) seine Auswahl nochmals bestätigt (siehe auch rechter Teil der Abbildung 6.1). Programm 6.1 dialog.cpp: Demoprogramm zur Klasse QDialog #include <qwidget.h> #include <qapplication.h> #include <qdialog.h> #include <qpushbutton.h> #include <qmessagebox.h> //... MeinDialog class MeinDialog : public QDialog { public: MeinDialog::MeinDialog( QWidget *parent, QString name, bool modal=true ) : QDialog( parent, name, modal ) { QPushButton *ok = new QPushButton( "OK", this ); ok->setgeometry( 10,10, 100,30 ); connect( ok, SIGNAL(clicked()), SLOT(accept()) ); if ( modal ) { QPushButton *cancel = new QPushButton( "Cancel", this ); cancel->setgeometry( 10,60, 100,30 ); connect( cancel, SIGNAL(clicked()), SLOT(reject()) ); ; //... main int main( int argc, char *argv[] ) { 419

55 6 Vordefinierte Dialogfenster QApplication a( argc, argv ); QWidget *w = new QWidget; w->setgeometry( 10, 10, 300, 300 ); w->setpalette( QPalette( Qt::blue, Qt::blue ) ); w->show(); if ( argc > 1 &&!strcmp( argv[1], "-m" ) ) { MeinDialog *modal = new MeinDialog( w, 0, true ); modal->setcaption( "Modaler Dialog" ); modal->setpalette( QPalette( Qt::red,Qt::red ) ); int r = modal->exec(); QString s; s.sprintf("du hast %s gedrueckt!", r == QDialog::Accepted? "OK" : "Cancel" ); QMessageBox::information( 0, "Nur zu deiner Info", s ); else { MeinDialog *nichtmodal = new MeinDialog( w, 0, false ); nichtmodal->setcaption( "Nicht-Modaler Dialog" ); nichtmodal->setpalette( QPalette( Qt::red, Qt::red ) ); nichtmodal->show(); a.setmainwidget( w ); return a.exec(); Übung: Dialog-Widget mit Checkboxen und mehreren Pushbuttons Erstellen Sie ein Programm dialog2.cpp, das ein Dialog-Widget mit Checkboxen einblendet, die der Benutzer ein- und ausschalten kann, sowie mit mehreren Buttons, die ihn seine Auswahl z. B. bestätigen oder ignorieren lassen. Unter Zuhilfenahme dieses Widget soll dann der Benutzer in den Checkboxen Länder auswählen können, zu denen er Flaggen angezeigt haben möchte (siehe auch Abbildung 6.2). Klickt der Benutzer auf den Ok-Button, werden ihm die Flaggen zu den Ländern angezeigt, die er in den Checkboxen ausgewählt hat. Bei einem Klick auf den Button Europäische sollen ihm in jedem Fall alle europäischen Flaggen und eventuell Abbildung 6.2: Eigenes Dialog-Widget zur Auswahl von Länderflaggen 420

56 6.2 Klasse QColorDialog zur Auswahl einer Farbe zusätzlich angeklickte Länderflaggen angezeigt werden. Klickt der Benutzer auf den Button Alle, sollen ihm unabhängig von seiner Auswahl in den Checkboxen alle Länderflaggen angezeigt werden. Ein Klick auf den Cancel-Button beendet unabhängig von der vorgenommenen Auswahl das Programm ohne jegliche Anzeige von Länderflaggen. 6.2 Klasse QColorDialog zur Auswahl einer Farbe Die Klasse QColorDialog bietet keine Konstruktoren an, sondern nur statische Funktionen, wie z. B. die Methode getcolor(), die ein Dialogfenster zur Auswahl einer Farbe einblendet: QColor QColorDialog::getColor(QColor initial, QWidget *parent=0, const char *name=0) Diese Funktion blendet ein modales Dialogfenster ein, das dem Benutzer eine Farbe auswählen lässt (siehe auch Abbildung 6.3). In diesem Dialogfenster ist die Farbe, die mit dem Parameter initial übergeben wird, voreingestellt. Die vom Benutzer ausgewählte Farbe liefert diese Funktion dann als Rückgabewert, nachdem dieser den Ok-Button gedrückt hat und das Dialogfenster wieder ausgeblendet wurde. Hat der Benutzer den Cancel-Button gedrückt, liefert diese Funktion einen ungültigen Farbenwert, der sich mit der von der Klasse QColor angebotenen Methode isvalid() erkennen lässt. Neben der statischen Methode getcolor() bietet die Klasse QColorDialog noch einige weitere statische Methoden an, wie z. B.: QRgb QColorDialog::getRgba(QRgb initial, bool *ok=0, QWidget *parent=0, const char *name=0) static: blendet wie getcolor() ein modales Dialogfenster ein, das dem Benutzer eine Farbe auswählen lässt. Anders als bei getcolor() hat der Benutzer hier noch die Möglichkeit, einen Alpha-Kanal (unterhalb des Blue-Eingabefelds) festzulegen. Ist für ok kein Nullzeiger angegeben, so wird *ok auf true gesetzt, wenn der Benutzer den Ok-Button gedrückt hat, bzw. auf false, wenn er den Cancel-Button gedrückt hat. int QColorDialog::customCount() static: liefert die Anzahl der als Custom colors im QColorDialog-Widgets festgelegten Farben. QRgb QColorDialog::customColor(int i) static: liefert die i-te festgelegte Farbe aus den Custom colors des QColorDialog-Widget. QColorDialog::setCustomColor(int i, QRgb c) static: setzt die i-te Farbe von Custom colors im QColorDialog-Widget auf den QRgb-Wert c. Programm 6.2 ist ein Demonstrationsprogramm zur Klasse QColorDialog. Dieses Programm bietet im Hauptfenster eine Widget-Fläche mit einem Button an, mit dem man sich ein QColorDialog-Fenster (siehe auch Abbildung 6.3) einblenden lassen kann, um eine neue Farbe auszuwählen. Nach abgeschlossener Auswahl und Bestätigung dieser Wahl mit dem Ok-Button wird die neu gewählte Farbe in 421

57 6 Vordefinierte Dialogfenster Abbildung 6.3: Ein QColorDialog-Fenster der Widget-Fläche des Hauptfensters als Hintergrundfarbe angezeigt (siehe auch Abbildung 6.4). Die zu Beginn voreingestellte Hintergundfarbe ist Weiß. Programm 6.2 colordialog.cpp: Demoprogramm zur Auswahl einer Farbe mit QColorDialog #include <qwidget.h> #include <qapplication.h> #include <qpushbutton.h> #include <qcolordialog.h> //... MeinFarbe Abbildung 6.4: Hauptfenster des Programms

58 6.3 Klasse QFileDialog zur Auswahl einer Datei class MeinFarbe : public QWidget { Q_OBJECT public: MeinFarbe::MeinFarbe() : QWidget( 0, 0) { setbackgroundcolor( aktfarbe = Qt::white ); farbebutton = new QPushButton( "Neue Farbe", this ); connect( farbebutton, SIGNAL( clicked() ), SLOT( neuefarbe() ) ); setgeometry( 0, 0, 400, 400 ); private slots: void neuefarbe() { QColor neufarbe; neufarbe = QColorDialog::getColor( aktfarbe, 0 ); if ( neufarbe.isvalid() ) { setbackgroundcolor( aktfarbe = neufarbe ); repaint(); private: QPushButton *farbebutton; QColor aktfarbe; ; #include "colordialog.moc" //... main int main( int argc, char *argv[] ) { QApplication a( argc, argv ); MeinFarbe *w = new MeinFarbe; w->show(); a.setmainwidget( w ); return a.exec(); Übung: Anzeige eines Textes in einer über QColorDialog gewählten Farbe Erstellen Sie ein Programm colordialog2.cpp, das ähnlich zu Programm 6.2 einen Button Neue Farbe und zusätzlich ein Label mit einem Text einblendet. Bei jedem Klick auf den Button Neue Farbe soll ein QColorDialog-Fenster eingeblendet werden, in dem der Benutzer eine neue Farbe wählen kann. Bestätigt er hier seine gewählte Farbe mit den Ok-Button, soll ihm der Text im Label mit dieser Farbe angezeigt werden. 6.3 Klasse QFileDialog zur Auswahl einer Datei Die Klasse QFileDialog bietet ein vordefiniertes Dialogfenster zur Auswahl eines Dateinamens an. 423

59 6 Vordefinierte Dialogfenster Konstruktoren und Methoden der Klasse QFileDialog Die Klasse QFileDialog bietet zwei Konstruktoren an: QFileDialog(QWidget *parent=0, const char *name=0, bool modal=false): erzeugt ein QFileDialog-Widget. Ob es sich dabei um ein modales oder nicht-modales Dialogfenster handelt, kann mit dem Parameter modal festgelegt werden. QFileDialog(const QString& dirname, const QString& filter=qstring::null, QWidget *parent=0, const char *name=0, bool modal=false): erzeugt ein QFileDialog-Widget. Der Parameter dirname legt den Namen des Directory fest, aus dem die entsprechenden Dateien (für eine Auswahl) anzuzeigen sind. Der Parameter filter spezifiziert den Filter, der für die Anzeige von Dateinamen zu benutzen ist. Als Filter sind dabei reguläre Ausdrücke erlaubt, wie sie in einem späteren Kapitel beschrieben sind. Dabei ist es auch erlaubt, Texte anzugeben, die zur Information für den Benutzer dienen. In diesem Fall muss der entsprechende reguläre Ausdruck am Ende des entsprechenden Textes in runden Klammern angegeben werden; so liefern z. B. die beiden folgenden Angaben die gleiche Anzeige von Dateinamen in dem QFileDialog-Widget, nur dass die erste Angabe etwas informativer ist: "Alle C-Header- und Quelldateien (*.[ch])" bzw. "*.[ch]". Es ist auch möglich, mehrere Filter anzugeben, indem man diese durch neue Zeilen oder zwei Semikola trennt, wie z. B. "C++ Dateien (*.cpp *.cc *.C *.cxx *.c++);;headerdateien (*.h *.hxx *.h++)". Ob es sich dabei um ein modales oder nicht-modales Dialogfenster handelt, kann mit dem Parameter modal festgelegt werden. Wichtige Methoden, die die Klasse QFileDialog anbietet, sind: QString getopenfilename(const QString& start- With=QString::null, const QString& filter=qstring::null, QWidget *parent=0, const char *name=0) static: Diese statische Funktion, die man verwenden kann, um ein QFileDialog-Fenster einzublenden, ohne dass man ein eigenes QFileDialog-Objekt anlegt, findet sehr häufige Anwendung. Sie öffnet ein modales QFileDialog-Fenster und liefert den vom Benutzer ausgewählten Dateinamen zurück. Wenn startwith ein Directoryname ist, startet der Dialog in diesem Directory. Ist startwith der Pfadname einer existierenden Datei, startet der Dialog in dem zugehörigen Directory, wobei der entsprechende Dateiname schon als ausgewählt angezeigt wird. Ist startwith ein Leerstring startet der Dialog im Working Directory und beim erneuten Aufrufen immer in dem Directory, in dem das letzte QFileDialog-Fenster beendet wurde. Sollen nur bestimmte Dateinamen im Dialogfenster angezeigt werden, so muss für den Parameter filter ein entsprechender regulärer Ausdruck angegeben werden. Falls für filter der Wert QString::null eingestellt wird, werden alle Dateinamen des entsprechenden Directory im Dialogfenster angezeigt. Falls der Benutzer das Dialogfenster mit dem Drücken des Cancel-Button beendet, liefert diese Funktion den null-string als Rückgabewert. Nachfolgend ist ein Beispiel für den Aufruf dieser Methode gezeigt: 424

60 6.3 Klasse QFileDialog zur Auswahl einer Datei //... im Working-Directory alle C++-Dateien mit der Endung.cpp anzeigen QString d = QFileDialog::getOpenFileName( QString::null, "*.cpp", this ); if (!d.isempty() ) { //... Benutzer hat eine existierende Datei ausgewählt else { //... Benutzer hat das Dialogfenster mit dem Cancel-Button beendet QStringList getopenfilenames(const QString& filter=qstring::null, const QString& dir=qstring::null, QWidget *parent=0, const char *name=0) static: Diese statische Funktion entspricht weitgehend der Funktion getopenfilename(), nur dass sie den Benutzer mehrere Dateien auswählen lässt und diese dann als Rückgabewert liefert, wie z. B.: QStringList s( QFileDialog::getOpenFileNames() ); //... Bearbeiten der Dateien in s QString getsavefilename(const QString& start- With=QString::null, const QString& filter=qstring::null, QWidget *parent=0, const char *name=0) static: Diese statische Funktion entspricht weitgehend der Funktion getopenfilename(), nur mit dem einzigen Unterschied, dass hier der Benutzer auch eine nicht existierende Datei auswählen kann, was ja beim Sichern von Dateien unter einem neuen Namen auch unbedingt notwendig ist. QString getexistingdirectory(const QString& dir=qstring::null, QWidget *parent=0, const char *name=0) static: Diese statische Funktion blendet ein Dialogfenster ein, in dem der Benutzer ein existierendes Directory auswählen kann, das sie als Rückgabewert liefert. Welches Directory dabei beim Start des Dialogfensters der Ausgangspunkt sein soll, kann mit dem Parameter dir festgelegt werden. Falls dir=null gilt, wird als Ausgangspunkt das Directory genommen, in dem das letzte QFileDialog-Fenster beendet wurde. setdir(const QString& pathstr) slot: legt einen Directorypfad für ein QFileDialog-Fenster fest. QString dirpath() const: liefert den aktuellen Directorypfad eines QFile- Dialog-Fensters zurück. setselection(const QString& filename): markiert in einem QFileDialog-Fenster den Dateinamen filename als ausgewählt. Falls es sich bei filename um einen absoluten Pfadnamen handelt, so wird automatisch auch set- Dir() aufgerufen. QString selectedfile() const: liefert zu der in einem QFileDialog- Fenster ausgewählten Datei den absoluten Pfadnamen. Falls kein Dateiname ausgewählt wurde, wird der null-string zurückgegeben. setfilter(const QString& newfilter) slot: legt für ein QFileDialog-Fenster einen neuen Filter fest, der als regulärer Ausdruck anzugeben ist, wie dies bereits beim zweiten Konstruktor zuvor beschrieben wurde. 425

61 6 Vordefinierte Dialogfenster setmode(mode newmode): legt für ein QFileDialog-Fenster einen neuen Modus fest. Für den Parameter newmode kann dabei eine der folgenden Konstanten angegeben werden: Directory: Auswahl von Directories ist erlaubt ExistingFile: Auswahl von existierenden Dateien ist erlaubt AnyFile: Angabe von beliebigen Dateinamen (ob existierend oder nicht) ist erlaubt DirectoryOnly: Nur Auswahl von Directories erlaubt; andere Dateien werden nicht angezeigt. ExistingFiles: wie ExistingFile, nur dass auch Auswahl mehrerer Dateien erlaubt ist addwidgets(qlabel *l, QWidget *w, QPushButton *b) protected: fügt bis zu drei Widgets unten in dem QFileDialog-Widget hinzu. l ist dabei ein (optionales) Label, welches unterhalb der Spalte angeordnet wird, in der sich die Texte File name und File type befinden. w ist ein (optionales) Widget, das unterhalb der Kombobox für den File type platziert wird. b ist ein (optionaler) Button, der unterhalb des Cancel-Button angesiedelt wird. Soll eines dieser optionalen Widgets nicht angezeigt werden, muss für den entsprechenden Parameter nur der Wert 0 angegeben werden. rereaddir(): zwingt ein QFileDialog-Fenster den entsprechenden Directoryinhalt erneut zu lesen. Dies kann notwendig sein, wenn sich der Directoryinhalt ändert, nachdem das QFileDialog-Fenster für dieses Directory schon eingeblendet war. Die Klasse QFileDialog bietet die folgenden Signale an: filehighlighted(const QString&) signal: wird gesendet, wenn der Benutzer einen Dateinamen markiert. fileselected(const QString&) signal: wird gesendet, wenn der Benutzer einen Dateinamen auswählt. direntered(const QString&) signal: wird gesendet, wenn der Benutzer ein neues Directory ausgewählt hat. Abbildung 6.5: QFileDialog-Fenster zur Auswahl einer Datei im Programm

62 6.3 Klasse QFileDialog zur Auswahl einer Datei Abbildung 6.6: Laden eines Bildes (links) bzw. eines Textes (rechts) im Programm 6.3 Die Klasse QFileDialog bietet noch weitere Methoden an, mit denen man z. B. unter Zuhilfenahme der Klasse QFilePreview eine Vorschau zu Dateien einblenden kann oder unter Verwendung der Klasse QFileIconProvider die Dateinamen abhängig von ihrem Inhalt mit entsprechenden Icons versehen kann. Auf eine tiefergehende Behandlung dieser Methoden wird hier verzichtet. Der interessierte Leser kann diese in der Qt-Online-Dokumentation nachschlagen. Beispiel: Editor, der Betrachtung/Konvertierung von Bildern ermöglicht Programm 6.3 ist ein Demonstrationsprogramm zur Klasse QFileDialog. Über ein QFileDialog-Fenster (siehe Abbildung 6.5) kann dabei der Benutzer sich eine Datei auswählen. Handelt es sich dabei um eine Bilddatei, deren Format Qt interpretieren kann, so wird ihm das entsprechende Bild angezeigt, wie dies z. B. im linken Teil von Abbildung 6.6 gezeigt ist. Kann Qt das Format der entsprechenden Datei nicht als ein ihm bekanntes Bildformat interpretieren, liest das Programm 6.3 diese Datei als Textdatei in ein QMultiLineEdit-Widget ein, welches das Editieren dieses Textes ermöglicht, wie dies z.b im rechten Teil von Abbildung 6.6 gezeigt ist. Das Speichern einer Datei ist dabei auch möglich, wie dies in Abbildung 6.7 gezeigt ist. Handelt es sich bei der entsprechenden Datei um ein Bild, so konvertiert das Programm 6.3 das Bild bei der Speicherung abhängig von der Dateiendung automatisch in das entsprechende Bildformat (.png,.gif,.bmp,.xbm,.xpm,.pnm). Programm 6.3 filedialog.cpp: Texteditor, der auch Betrachtung und Konvertierung von Bildern ermöglicht #include <qapplication.h> #include <qlabel.h> #include <qmultilinedit.h> #include <qfiledialog.h> #include <qmenubar.h> 427

63 6 Vordefinierte Dialogfenster Abbildung 6.7: QFileDialog-Fenster zur Auswahl eines Dateinamens zur Speicherung im Programm 6.3 #include <qpopupmenu.h> #include <qtextstream.h> #include <qmessagebox.h> enum { SchliessenID=255, SpeichernID, SpeichernUnterID ; //========================================================================== // V i e w e r - K l a s s e //========================================================================== class Viewer : public QWidget { Q_OBJECT // notwendig, da Slots enthalten sind public: Viewer(); private slots: void schliessenslot() { //... schliessenslot if ( view!= NULL ) { delete view; view = NULL; dateiname = ""; setzetitel( "keine" ); dateimenu->setitemenabled( SchliessenID, false ); dateimenu->setitemenabled( SpeichernID, false ); dateimenu->setitemenabled( SpeichernUnterID, false ); void beendenslot() { //... beendenslot schliessenslot(); qapp->quit(); void oeffnenslot() { //... oeffnenslot QString name = QFileDialog::getOpenFileName( ".", "*", this ); if (!name.isempty() ) { dateiname = name; schliessenslot(); lesedatei(); dateimenu->setitemenabled( SchliessenID, true ); dateimenu->setitemenabled( SpeichernID, true ); dateimenu->setitemenabled( SpeichernUnterID, true ); 428

64 6.3 Klasse QFileDialog zur Auswahl einer Datei void speichernslot() { //... speichernslot if (view!= NULL) speicheredatei( false ); void speichernunterslot() { //... speichernunterslot if (view!= NULL) speicheredatei( true ); protected: virtual void resizeevent( QResizeEvent* ) { //... resizeevent if (view!= NULL) { view->setgeometry( 0, menubalken->height(), width(), height() - menubalken->height() ); if ( istbild ) bildview->setgeometry( 0,0, width(),height()-menubalken->height() ); else textview->setgeometry( 0,0, width(),height()-menubalken->height() ); repaint(); private: void lesedatei() { //... lesedatei QFile datei; if (!dateiname.isempty() ) { datei.setname( dateiname ); setzetitel( dateiname ); view = new QWidget( this ); if ( bild.load( dateiname ) ) { bildview = new QScrollView( view ); bildview->viewport()->setbackgroundcolor( Qt::white ); QLabel *l = new QLabel( bildview->viewport() ); l->setpixmap( bild ); l->setframestyle( QFrame::Box QFrame::Sunken ); l->setlinewidth( 4 ); l->resize( l->sizehint() ); istbild = true; bildview->addchild( l ); bildview->setgeometry( 0,0, width(),height()-menubalken->height() ); else if ( datei.open(io_readonly) ) { QTextStream text( &datei ); // verwende einen text stream QString s; textview = new QMultiLineEdit( view ); while (!text.eof() ) { s = text.readline(); textview->insertline( s ); datei.close(); istbild = false; textview->setgeometry( 0,0,width(),height()-menuBalken->height() ); view->setgeometry( 0, menubalken->height(), width(), height() - menubalken->height() ); 429

65 6 Vordefinierte Dialogfenster view->show(); void speicheredatei( bool neuername ) { //... speicheredatei if ( dateiname.isempty() neuername == true ) dateiname = QFileDialog::getSaveFileName( ".", "*", this ); if (!dateiname.isempty() ) { setzetitel( dateiname ); if ( istbild ) { QString extension = dateiname.mid( dateiname.findrev(. )+1 ).upper(); if (!bild.save( dateiname, extension ) ) QMessageBox::information( this, "Fehler", extension+"-format wird nicht unterstützt"); else { QFile datei; datei.setname( dateiname ); if ( datei.open(io_writeonly) ) { QString text = textview->text(); datei.writeblock( text, strlen(text) ); datei.close(); void setzetitel( QString dateiname ) { //... setzetitel QString s = "Viewer - Datei: "; s += dateiname; setcaption( s ); //... private-variablen QMenuBar *menubalken; QPopupMenu *dateimenu; QString dateiname; QWidget *view; QMultiLineEdit *textview; QScrollView *bildview; QPixmap bild; bool istbild; ; #include "filedialog.moc" //========================================================================== // V i e w e r - K o n s t r u k t o r //========================================================================== Viewer::Viewer() { view = NULL; dateiname = ""; setzetitel( "keine"); dateimenu = new QPopupMenu; //... erzeugt ein Datei-Menue dateimenu->insertitem( "Oe&ffnen...", this, SLOT( oeffnenslot() ), CTRL+Key_O ); 430

66 6.4 Klasse QFontDialog zur Auswahl eines Font dateimenu->insertitem( "S&chliessen", this, SLOT( schliessenslot() ), CTRL + Key_W, SchliessenID ); dateimenu->setitemenabled( SchliessenID, false ); dateimenu->insertseparator(); dateimenu->insertitem( "&Speichern", this, SLOT( speichernslot() ), CTRL + Key_S, SpeichernID ); dateimenu->setitemenabled( SpeichernID, false ); dateimenu->insertitem( "Speichern &unter...", this, SLOT( speichernunterslot() ), CTRL + Key_U, SpeichernUnterID ); dateimenu->setitemenabled( SpeichernUnterID, false ); dateimenu->insertseparator(); dateimenu->insertitem( "&Beenden", this, SLOT( beendenslot() ), CTRL+Key_Q ); menubalken = new QMenuBar( this ); //... erzeugt einen Menue-Balken menubalken->insertitem( "&Datei", dateimenu ); //========================================================================== // m a i n //========================================================================== int main( int argc, char* argv[] ) { QApplication myapp( argc, argv ); Viewer* mywidget = new Viewer(); mywidget->setgeometry( 10, 10, 600, 600 ); myapp.setmainwidget( mywidget ); mywidget->show(); return myapp.exec(); Übung: Anzeige ausgewählter Dateinamen in einem Label Erstellen Sie ein Programm filedialog2.cpp, das eine Erweiterung zum Übungsprogramm colordialog2.cpp auf Seite 423 ist, indem es nicht nur einen Farbe-Button, sondern auch einen Dateinamen-Button zeigt. Klickt der Benutzer auf diesen zweiten Button, soll ihm ein QFileDialog-Widget eingeblendet werden, in dem er auch mehrere Dateinamen gleichzeitig auswählen kann (mit QFileDialog::getOpenFileNames()), indem er bei dem Anklicken der Dateinamen die Strg -Taste drückt. Nachdem der Benutzer seine Auswahl mit Ok bestätigt hat, sollen ihm die ausgewählten Dateinamen in der aktuellen Farbe angezeigt werden; siehe auch Abbildung Klasse QFontDialog zur Auswahl eines Font Die Klasse QFontDialog bietet ein vordefiniertes Dialogfenster zur Auswahl eines Font an. 431

67 6 Vordefinierte Dialogfenster Abbildung 6.8: Anzeige von ausgewählten Dateinamen in einem Label Wichtige Methoden der Klasse QFontDialog Die Klasse QFontDialog bietet keine public-konstruktoren an, sondern nur eine statische Funktion getfont(), die ein Dialogfenster zur Auswahl eines Font einblendet und in zwei Varianten angeboten wird: QFont getfont(bool *ok, QWidget *parent=0,const char *name=0) static: Diese Funktion blendet ein modales Dialogfenster ein, das den Benutzer einen Font auswählen lässt (siehe auch Abbildung 6.10). Den vom Benutzer ausgewählten Font liefert diese Funktion dann als Rückgabewert, nachdem dieser den Ok-Button gedrückt hat und das Dialogfenster wieder ausgeblendet wurde. Ob der Benutzer den Ok-Button gedrückt hat, lässt sich am Wert des Parameters ok erkennen. Ist *ok=true, hat er den Ok-Button gedrückt; bei *ok=false hat er das QFontDialog-Fenster mit dem Cancel-Button beendet oder eben anders geschlossen. Bei *ok=false liefert diese Funktion den voreingestellten Font zurück. Beispiel: bool ok; QFont f = QFontDialog::getFont( &ok, this ); if ( ok ) { //... Benutzer hat einen neuen Font ausgewählt else { //... Benutzer hat Dialogfenster mit Cancel-Button oder anders beendet QFont getfont(bool *ok, const QFont& initial, QWidget *parent=0, const char *name=0) static: Diese Variante entspricht weitgehend der vorhergehenden Aufrufvariante, nur dass im QFontDialog-Fenster der über den Parameter initial übergebene Font voreingestellt wird. 432

68 6.4 Klasse QFontDialog zur Auswahl eines Font Abbildung 6.9: Angezeigtes Hauptfenster beim Start von Programm 6.4 Beispiel: bool ok; QFont f = QFontDialog::getFont( &ok, QFont( "Times", 12 ), this ); if ( ok ) { //... Benutzer hat einen neuen Font ausgewählt else { //... Benutzer hat Dialogfenster mit Cancel-Button oder anders beendet Abbildung 6.10: QFontDialog-Fenster zur Auswahl eines Font im Programm

69 6 Vordefinierte Dialogfenster Abbildung 6.11: Hauptfenster im Programm 6.4, nachdem Benutzer neuen Font gewählt hat Beispiel: Demonstrationsprogramm zur Klasse QFontDialog Programm 6.4 zeigt in seinem Hauptfenster (siehe Abbildung 6.9) in einem Label den gerade gesetzten Font in Form eines Beispieltextes (Text) an. Die dazugehörigen Font-Daten werden in einem darunter angeordneten Label angezeigt. Als letztes bietet dieses Programm noch einen Button an, mit dem man sich ein QFontDialog-Fenster einblenden lassen kann, um einen neuen Font auszuwählen. Drückt der Benutzer auf diesen Button, wird ihm ein solches neues QFontDialog-Fenster eingeblendet, in dem er nun seine entsprechenden Font-Einstellungen vornehmen kann, wie dies z. B. in Abbildung 6.10 gezeigt ist. Drückt der Benutzer in diesem QFileDialog-Fenster den Ok-Button, werden ihm im Hauptfenster der Beispieltext Text in seinem gewählten Font sowie die zugehörigen Font-Daten angezeigt (siehe auch Abbildung 6.11). Programm 6.4 fontdialog.cpp: Demoprogramm zur Klasse QFontDialog #include <qwidget.h> #include <qapplication.h> #include <qvbox.h> #include <qpushbutton.h> #include <qlabel.h> #include <qfont.h> #include <qfontdialog.h> //... MeinFont class MeinFont : public QVBox { Q_OBJECT public: 434

70 6.4 Klasse QFontDialog zur Auswahl eines Font MeinFont::MeinFont() : QVBox( 0, 0) { //... Vertikaler Layoutmanger QVBox *v = new QVBox( this ); v->setspacing( 20 ); v->setmargin( 20 ); v->setbackgroundcolor( Qt::blue.light( 180 ) ); //... Label zur Anzeige des aktuellen Fonts fontanzeige = new QLabel( "Text", v ); fontanzeige->setbackgroundcolor( Qt::white ); fontanzeige->setalignment( AlignCenter ); aktfont = fontanzeige->font(); //... Label zur Anzeige der aktuellen Fontdaten fontdaten = new QLabel( "", v ); fontdaten->settext( fonttostring() ); fontdaten->setalignment( AlignCenter ); //... Buttom zum Einblenden QFontDialog-Fensters fontbutton = new QPushButton( "Neuer Font", v ); fontbutton->setpalette( QPalette( Qt::red, Qt::red ) ); connect( fontbutton, SIGNAL( clicked() ), SLOT( neuerfont() ) ); setgeometry( 0, 0, 400, 400 ); private slots: void neuerfont() { QFont neufont; bool ok; neufont = QFontDialog::getFont( &ok, aktfont ); if ( ok ) { fontanzeige->setfont( aktfont = neufont ); fontanzeige->repaint(); fontdaten->settext( fonttostring() ); fontdaten->repaint(); private: QFont aktfont; QLabel *fontanzeige; QLabel *fontdaten; QPushButton *fontbutton; //... liefert die Font-Daten als String zurueck. //... Dazu ruft diese Funktion die von der Klasse QFont angebotenen //... Methoden family(), weight(), italic() pointsize(), //... underline() und strikeout() auf. QString fonttostring() { QString s, weight; switch ( aktfont.weight() ) { case QFont::Light: weight = "Light"; break; case QFont::Normal: weight = "Normal"; break; case QFont::DemiBold: weight = "DemiBold"; break; case QFont::Bold: weight = "Bold"; break; case QFont::Black: weight = "Black"; break; 435

71 6 Vordefinierte Dialogfenster s.sprintf("%s-%s-%s-%d\n\n%sunderline-%sstrikeout\n", (const char *)aktfont.family(), (const char *)weight, (const char *)aktfont.italic()? "Italic" : "", aktfont.pointsize(), (const char *)aktfont.underline()? "" : "No", (const char *)aktfont.strikeout()? "" : "No" ); return s; ; #include "fontdialog.moc" //... main int main( int argc, char *argv[] ) { QApplication a( argc, argv ); MeinFont *w = new MeinFont; w->setgeometry( 20, 20, 400, 400 ); w->show(); a.setmainwidget( w ); return a.exec(); Übung: Erweiterung des Übungsprogramms aus Kapitel 6.4 um Fonts Erstellen Sie ein Programm fontdialog2.cpp, das eine Erweiterung zum Übungsprogramm filedialog2.cpp auf Seite 431 ist, indem es nicht nur einen Farbe-Button und einen Dateinamen-Button, sondern auch einen Font-Button zeigt. Klickt der Benutzer auf diesen dritten Button, soll ihm ein QFontDialog-Widget eingeblendet werden, in dem er sich einen entsprechenden Font für die Anzeige der Dateinamen im Label auswählen kann. 6.5 Klasse QMessageBox für Mitteilungen Die Klasse QMessageBox ermöglicht es, den Benutzer über Situationen, Ereignisse oder Bedingungen zu informieren, die eingetreten sind oder aber eintreten könnten. QMessageBox-Dialogfenster sind fast immer modal. Typen, Konstruktoren und Methoden der Klasse QMessageBox Die Klasse QMessageBox bietet zwei eigene enum-datentypen an: enum Icon { NoIcon=0, Information=1, Warning=2, Critical=3 : Diese Konstanten legen das Icon (Bildchen) fest, das im QMessageBox-Fenster anzuzeigen ist: NoIcon: kein Icon Information: (Buchstabe,i in einer Sprechblase) wird verwendet, wenn man dem Benutzer lediglich eine Information zukommen lassen möchte. 436

72 6.5 Klasse QMessageBox für Mitteilungen Warning: (Ausrufezeichen in einem Warnschild) wird verwendet, wenn man den Benutzer warnen möchte. Critical: (weißes,x in einem schwarzen Kreis) wird verwendet, um den Benutzer auf eine kritische Situation hinzuweisen, die eingetreten ist oder eintreten könnte. enum { Ok=1, Cancel=2, Yes=3, No=4, Abort=5, Retry=6, Ignore=7, ButtonMask=0x07, Default=0x100, Escape=0x200, Flag- Mask=0x300 : Diese Konstanten identifizieren Texte bzw. Einstellungen für Buttons, die in einem QMessageBox-Fenster angezeigt werden. Die Klasse QMessageBox bietet zwei Konstruktoren an: QMessageBox(QWidget *parent=0, const char *name=0): erzeugt ein QMessageBox-Widget, das keinerlei Text, aber einen Button mit der Beschriftung Ok enthält. QMessageBox(const QString& caption, const QString& text, Icon icon, int button0, int button1, int button2, QWidget *parent=0, const char *name=0, bool modal=true, WFlags f=wstyle_dialogborder): Bei dieser Konstruktor-Variante wird ein QMessageBox-Widget erzeugt, dessen Titel durch den Parameter caption und dessen Informationstext durch den Parameter text festgelegt ist. Für den Parameter icon ist eine der folgenden Konstanten anzugeben: QMessageBox::NoIcon QMessageBox::Information QMessageBox::Warning QMessageBox::Critical Für die drei Parameter button0, button1 und button2 ist eine der folgenden Konstanten anzugeben: QMessageBox::Ok QMessageBox::Cancel QMessageBox::Yes QMessageBox::No QMessageBox::Abort QMessageBox::Retry QMessageBox::Ignore Einer dieser drei Buttons kann mit bitweisem OR mit der Konstante QMessage- Box::Default verknüpft werden, was ihn zum Default-Button macht. Der Default-Button ist der Button, auf den automatisch der Tastaturfokus eingestellt wird und der so direkt durch Drücken der ¹ -Taste ausgewählt (gedrückt) werden kann. Einer dieser drei Buttons kann mit bitweisem OR mit der Konstante QMessage- Box::Escape verknüpft werden, was ihn mit der ESC -Taste verbindet. Dies bedeutet, dass beim Drücken der ESC -Taste (auf der Tastatur) immer dieser Button aktiviert wird, so als ob man auf diesen Button mit der Maus geklickt hätte. Der Parameter modal schließlich legt fest, ob ein modales oder ein nicht-modales QMessageBox-Widget zu erzeugen ist. 437

73 6 Vordefinierte Dialogfenster Nachfolgend ist ein kleiner Codeausschnitt für ein Nachrichtenfenster gezeigt, das beim Beenden eines Editors eingeblendet wird, wenn der Benutzer den Editor verlassen möchte, ohne dass er zuvor seine Datei gesichert hat. QMessageBox mb( "Datei noch nicht gesichert", "Was soll geschehen?", QMessageBox::Information, QMessageBox::Yes QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel QMessageBox::Escape ); mb.setbuttontext( QMessageBox::Yes, "Sichern" ); mb.setbuttontext( QMessageBox::No, "Nicht sichern" ); mb.setbuttontext( QMessageBox::Cancel, "Abbrechen" ); switch ( mb.exec() ) { case QMessageBox::Yes: //... Datei speichern und Editor verlassen break; case QMessageBox::No: //... Datei nicht speichern und Editor verlassen break; case QMessageBox::Cancel: //... Datei nicht speichern und Editor nicht vwerlasse break; Man kann jedoch auch direkt ein QMessageBox-Fenster einblenden, ohne explizit ein Objekt dazu mittels eines Konstruktors anzulegen. Dazu bietet Qt die folgenden statischen Methoden an: int information(qwidget *parent, const QString& caption, const QString& text, const QString& button0text=qstring::null, const QString& button1text=qstring::null, const QString& button2text=qstring::null, int defaultbuttonnumber=0, int escapebuttonnumber=-1) static: blendet ein QMessageBox-Fenster des Typs Information ein, dessen Titel durch den Parameter caption und dessen Informationstext durch den Parameter text festgelegt wird. Die nächsten drei Parameter buttonxtext spezifizieren den Text für die einzelnen Buttons (bis zu drei). Ist für button0text kein Argument angegeben, wird hierfür ein Ok-Button angezeigt, während ein Weglassen der beiden letzten optionalen Buttons dazu führt, dass diese Buttons überhaupt nicht angezeigt werden. Der Parameter defaultbuttonnumber spezifiziert dann den Default- Button (0, 1 oder 2) und der Parameter escapebuttonnumber spezifiziert den Escape-Button (0, 1 oder 2). Diese Funktion liefert die Nummer des Button, den der Benutzer gedrückt hat, als Rückgabewert (0, 1 oder 2). int information(qwidget *parent, const QString& caption, const QString& text, int button0, int button1=0, int button2=0) static: blendet ein QMessageBox-Fenster des Typs Information ein, dessen Titel durch den Parameter caption und dessen Informationstext 438

74 6.5 Klasse QMessageBox für Mitteilungen durch den Parameter text festgelegt wird. Dieses QMessageBox-Fenster enthält bis zu drei Buttons, deren Text der Benutzer durch die entsprechenden Kennungen (Ok, Cancel, Yes,...) festlegen kann. Die Angabe von 0 für einen der Parameter button0, button1 oder button2 legt fest, dass dieser Button nicht anzuzeigen ist. Diese Funktion liefert die Nummer des Button, den der Benutzer gedrückt hat, als Rückgabewert (0, 1 oder 2). int warning(qwidget *parent, const QString& caption, const QString& text, const QString& button0text=qstring::null, const QString& button1text=qstring::null, const QString& button2text=qstring::null, int defaultbuttonnumber=0, int escapebuttonnumber=-1) static: entspricht der entsprechenden information()-methode (siehe oben), nur dass das eingeblendete QMessageBox- Fenster vom Typ Warning ist. int warning(qwidget *parent, const QString& caption, const QString& text, int button0, int button1=0, int button2=0) static: entspricht der entsprechenden information()-methode (siehe oben), nur dass das eingeblendete QMessageBox-Fenster vom Typ Warning ist. int critical(qwidget *parent, const QString& caption, const QString& text, const QString& button0text=qstring::null, const QString& button1text=qstring::null, const QString& button2text=qstring::null, int defaultbuttonnumber=0, int escapebuttonnumber=-1) static: entspricht der entsprechenden information()-methode (siehe oben), nur dass das eingeblendete QMessageBox- Fenster vom Typ Critical ist. int critical(qwidget *parent, const QString& caption, const QString& text, int button0, int button1=0, int button2=0) static: entspricht der entsprechenden information()-methode (siehe oben), nur dass das eingeblendete QMessageBox-Fenster vom Typ Critical ist. about(qwidget *parent, const QString& caption, const QString& text) static: Diese statische Methode blendet ein QMessageBox-Widget mit dem Titel caption und dem Informationstext text ein, in dem sich lediglich ein Ok-Button befindet (siehe auch linken Teil in Abbildung 3.9 auf Seite 167). aboutqt(qwidget *parent, const QString& caption=qstring::null) static: Diese statische Methode blendet ein QMessageBox-Widget mit dem Titel caption und einigen Informationen zu Qt (wie z. B. die Versionsnummer) als Informationstext ein; in diesem QMessageBox-Widget befindet sich lediglich ein Ok-Button (siehe auch rechten Teil in Abbildung 3.9 auf Seite 167). Nachfolgend werden nun noch einige Methoden vorgestellt, mit denen man nachträglich ein zuvor mit einem Konstruktor erzeugtes QMessageBox-Objekt entsprechend konfigurieren kann: settext(const QString& text): legt den anzuzeigenden Informationstext für ein QMessageBox-Objekt fest. 439

75 6 Vordefinierte Dialogfenster Abbildung 6.12: Hauptfenster im Programm 6.5 zur Konfiguration einer QMessageBox seticon(icon icon): legt das anzuzeigende Icon (NoIcon, Information, Warning, Critical) für ein QMessageBox-Objekt fest. seticonpixmap(const QPixmap& pixmap): ermöglicht es, ein benutzerdefiniertes Icon (pixmap) für ein QMessageBox-Objekt festzulegen. setbuttontext(int button, const QString& text): legt in einem Q- MessageBox-Objekt für den entsprechenden button, der die hier angegebene Kennung (Ok, Cancel, Yes, No, Abort, Retry, Ignore) besitzt, den anzuzeigenden text fest. Beispiel: Demonstrationsprogramm zur Klasse QMessageBox Programm 6.5 bietet über eine Menüleiste alle möglichen Konfigurationen für ein QMessageBox-Widget an (siehe Abbildung 6.12). Nachdem der Benutzer eine neue Konfiguration über einen Eintrag in dieser Menüleiste vorgenommen hat, wird ihm das entsprechende QMessageBox-Widget eingeblendet (siehe auch Abbildung 6.13). Nachdem der Benutzer dieses QMessageBox-Widget mit einem Klick auf einen der drei Buttons beendet hat, wird ihm in einem neuen QMessageBox-Fenster vom Typ Information seine Auswahl bestätigt (siehe auch Abbildung 6.14). Abbildung 6.13: Anzeige des konfigurierten QMessageBox-Fensters im Programm

76 6.5 Klasse QMessageBox für Mitteilungen Abbildung 6.14: Anzeige der Benutzerwahl aus Abbildung 6.13 im Programm 6.5 Programm 6.5 messagebox.cpp: Demoprogramm zur Klasse QMessageBox #include <qapplication.h> #include <qmenubar.h> #include <qpopupmenu.h> #include <qlineedit.h> #include <qmessagebox.h> #include <stdio.h> const int texteid = 0x1000; const int IconId = 0x2000; const int ButtonId = 0x3000; const int DefaultId = 0x4000; const int EscId = 0x5000; enum { CaptionId=texteId, InfotextId ; enum { NoIconId=IconId, InformationId, WarningId, CriticalId ; enum { OkId=ButtonId, CancelId, YesId, NoId, AbortId, RetryId, IgnoreId ; //... Klasse MyWidget class MyWidget : public QWidget { Q_OBJECT // notwendig, da Slots enthalten sind public: MyWidget() { // MyWidget (Konstruktor) //... Initialisierungen caption = ""; infotext = "Informationstext"; defaultbutton = 0; escbutton = 2; icon = QMessageBox::NoIcon; button[0] = QMessageBox::Yes QMessageBox::Default; button[1] = QMessageBox::No; button[2] = QMessageBox::Cancel QMessageBox::Escape; //...Texte-Menu textemenu = new QPopupMenu; textemenu->insertitem( "Caption", CaptionId ); textemenu->insertitem( "Infotext", InfotextId ); QObject::connect( textemenu, SIGNAL( activated( int ) ), this, SLOT( texteslot( int ) ) ); lc = new QLineEdit( caption, this ); li = new QLineEdit( infotext, this ); lc->setgeometry(10, 30, 100, 30 ); li->setgeometry(10, 30, 100, 30 ); lc->hide(); li->hide(); QObject::connect( lc, SIGNAL( returnpressed() ), 441

77 6 Vordefinierte Dialogfenster 442 this, SLOT( neuercaptionslot() ) ); QObject::connect( li, SIGNAL( returnpressed() ), this, SLOT( neuerinfotextslot() ) ); //... Icon-Menu iconmenu = new QPopupMenu; iconmenu->insertitem( "NoIcon", NoIconId ); iconmenu->insertitem( "Information", InformationId ); iconmenu->insertitem( "Warning", WarningId ); iconmenu->insertitem( "Critcal", CriticalId ); iconmenu->setitemchecked( NoIconId, true ); QObject::connect( iconmenu, SIGNAL( activated( int ) ), this, SLOT( iconslot( int ) ) ); //... button-menues for (int i=0; i<3; i++) { buttonmenu[i] = new QPopupMenu; buttonmenu[i]->insertitem( "Ok", OkId ); buttonmenu[i]->insertitem( "Cancel", CancelId ); buttonmenu[i]->insertitem( "Yes", YesId ); buttonmenu[i]->insertitem( "No", NoId ); buttonmenu[i]->insertitem( "Abort", AbortId ); buttonmenu[i]->insertitem( "Retry", RetryId ); buttonmenu[i]->insertitem( "Ignore", IgnoreId ); buttonmenu[0]->setitemchecked( YesId, true ); buttonmenu[1]->setitemchecked( NoId, true ); buttonmenu[2]->setitemchecked( CancelId, true ); QObject::connect( buttonmenu[0], SIGNAL( activated( int ) ), this, SLOT( button0slot( int ) ) ); QObject::connect( buttonmenu[1], SIGNAL( activated( int ) ), this, SLOT( button1slot( int ) ) ); QObject::connect( buttonmenu[2], SIGNAL( activated( int ) ), this, SLOT( button2slot( int ) ) ); //... Default-Menu defaultmenu = new QPopupMenu; defaultmenu->insertitem( "Button0", DefaultId ); defaultmenu->insertitem( "Button1", DefaultId+1 ); defaultmenu->insertitem( "Button2", DefaultId+2 ); defaultmenu->setitemchecked( DefaultId+defaultButton, true ); QObject::connect( defaultmenu, SIGNAL( activated( int ) ), this, SLOT( defaultslot( int ) ) ); //... Esc-Menu escmenu = new QPopupMenu; escmenu->insertitem( "Button0", EscId ); escmenu->insertitem( "Button1", EscId+1 ); escmenu->insertitem( "Button2", EscId+2 ); escmenu->setitemchecked( EscId+escButton, true ); QObject::connect( escmenu, SIGNAL( activated( int ) ), this, SLOT( escslot( int ) ) ); //... Menu-Balken menubalken = new QMenuBar( this );

78 6.5 Klasse QMessageBox für Mitteilungen menubalken->insertitem( "Texte", textemenu ); menubalken->insertitem( "Icon", iconmenu ); menubalken->insertitem( "Button0", buttonmenu[0] ); menubalken->insertitem( "Button1", buttonmenu[1] ); menubalken->insertitem( "Button2", buttonmenu[2] ); menubalken->insertitem( "Default", defaultmenu ); menubalken->insertitem( "Esc", escmenu ); private slots: void texteslot( int s ) { // Slots switch ( s ) { case CaptionId : lc->show(); break; case InfotextId: li->show(); break; void neuercaptionslot() { caption = lc->text(); lc->hide(); neuemessagebox(); void neuerinfotextslot() { infotext = li->text(); li->hide(); neuemessagebox(); void iconslot( int s ) { switch ( s ) { case NoIconId : icon = QMessageBox::NoIcon; break; case InformationId: icon = QMessageBox::Information; break; case WarningId : icon = QMessageBox::Warning; break; case CriticalId : icon = QMessageBox::Critical; break; for (int i=noiconid; i <= CriticalId; i++) iconmenu->setitemchecked( i, s == i ); neuemessagebox(); void button0slot( int s ) { buttonconfigure( s, 0); void button1slot( int s ) { buttonconfigure( s, 1); void button2slot( int s ) { buttonconfigure( s, 2); void defaultslot( int s ) { button[defaultbutton] &= ~QMessageBox::Default; button[defaultbutton=s-defaultid] = QMessageBox::Default; for (int i=defaultid; i <= DefaultId+2; i++) defaultmenu->setitemchecked( i, s == i ); neuemessagebox(); void escslot( int s ) { button[escbutton] &= ~QMessageBox::Escape; button[escbutton=s-escid] = QMessageBox::Escape; for (int i=escid; i <= EscId+2; i++) 443

79 6 Vordefinierte Dialogfenster escmenu->setitemchecked( i, s == i ); neuemessagebox(); private: void buttonconfigure( int s, int n ) { switch ( s ) { case OkId : button[n] = QMessageBox::Ok; break; case CancelId: button[n] = QMessageBox::Cancel; break; case YesId : button[n] = QMessageBox::Yes; break; case NoId : button[n] = QMessageBox::No; break; case AbortId : button[n] = QMessageBox::Abort; break; case RetryId : button[n] = QMessageBox::Retry; break; case IgnoreId: button[n] = QMessageBox::Ignore; break; if ( n == defaultbutton ) button[n] = QMessageBox::Default; if ( n == escbutton ) button[n] = QMessageBox::Escape; for (int i=okid; i <= IgnoreId; i++) buttonmenu[n]->setitemchecked( i, s == i ); neuemessagebox(); void neuemessagebox() { QString neuinfotext; neuinfotext.sprintf("%s\n\n\n" " (Button%d = Default-Button)\n" " (Button%d = Escape-Button)\n", (const char *)infotext, defaultbutton, escbutton); QMessageBox *mb = new QMessageBox( caption, neuinfotext, icon, button[0], button[1], button[2], this ); mb->setpalette( QPalette( Qt::red, Qt::red ) ); int ret = mb->exec(); delete mb; QString info = "Du hast den Button\""; switch ( ret ) { case QMessageBox::Ok: info+= "Ok"; break; case QMessageBox::Cancel: info+= "Cancel"; break; case QMessageBox::Yes: info+= "Yes"; break; case QMessageBox::No: info+= "No"; break; case QMessageBox::Abort: info+= "Abort"; break; case QMessageBox::Retry: info+= "Retry"; break; case QMessageBox::Ignore: info+= "Ignore"; break; info += "\" gewaehlt"; QMessageBox::information( this, "Nur zur Info", info ); QMenuBar *menubalken; QPopupMenu *textemenu, *iconmenu, *buttonmenu[3], *defaultmenu, *escmenu; QString caption, infotext; int button[3], defaultbutton, escbutton; QLineEdit *lc, *li; QMessageBox::Icon icon; 444

80 6.5 Klasse QMessageBox für Mitteilungen Abbildung 6.15: Auswahl eines Landes über Messageboxen ; #include "messagebox.moc" //... main int main( int argc, char* argv[] ) { QApplication myapp( argc, argv ); MyWidget*mywidget = new MyWidget(); mywidget->setgeometry( 10, 10, 400, 300 ); mywidget->setpalette( QPalette( Qt::lightGray, Qt::blue ) ); myapp.setmainwidget( mywidget ); mywidget->show(); return myapp.exec(); Übung: Auswahl eines Landes und Anzeige dessen Flagge Erstellen Sie ein Programm messagebox2.cpp, das zunächst eine Messagebox einblendet, wie sie links in Abbildung 6.15 gezeigt ist. Klickt der Benutzer den Button Weiter, wird ihm eine nächste Wahlmöglichkeit gezeigt (siehe Mitte in Abbildung 6.15). Klickt der Benutzer auch hier wieder auf den Button Weiter, wird ihm eine dritte und letzte Wahlmöglichkeit gezeigt (siehe rechts in Abbildung 6.15). Sollte er sich auch hier nicht für ein Land entscheiden können und klickt nun auf den Button None, wird ihm schließlich noch eine letzte Messagebox (siehe Abbildung 6.16) eingeblendet, in der er lediglich mit einem Klick auf den Ok-Button das Programm beenden kann. Sollte der Benutzer sich aber in einer der drei Messageboxen aus Abbildung 6.15 für ein Land entschieden haben, wird ihm die Flagge dieses Landes als Icon in einer Messagebox eingeblendet, wie dies beispielhaft für die Länder Britain und USA in Abbildung 6.17 gezeigt ist. Abbildung 6.16: Messagebox, wenn Benutzer kein Land auswählte 445

81 6 Vordefinierte Dialogfenster Abbildung 6.17: Anzeige der Flagge des gewählten Landes in einer Messagebox 6.6 Klasse QTabDialog zur Stapelung von Widgets im Karteikartenformat Die Klasse QTabDialog ermöglicht die Stapelung von Widgets im Karteikartenformat, von denen über eine Karteikartenreiterleiste (Tableiste) immer eines in den Vordergrund gebracht werden kann. Konstruktor und Methoden der Klasse QTabDialog Die Klasse QTabDialog bietet einen Konstruktor an: QTabDialog(QWidget *parent=0, const char *name=0, bool modal=false, Wflags f=0) erzeugt ein QTabDialog-Widget mit einem Ok-Button. Die übliche Vorgehensweise beim Programmieren einer QTabDialog-Anwendung ist die folgende: 1. Erzeugen eines QTabDialog-Widget (mit dem obigen Konstruktor). 2. Erzeugen von QWidget-Objekten für jede Seite, die in diesem QTabDialog- Widget untergebracht werden sollen. 3. Einfügen der entsprechenden Subwidgets (eventuell unter Verwendung von Layout-Managern) in die einzelnen QWidget-Objekte der entsprechenden Seiten. 4. Aufrufen der Methode addtab(), um die einzelnen Seiten (QWidget-Objekte) in dem QTabDialog-Widget einzuordnen. 5. Einrichten der einzelnen Buttons (Apply, Cancel usw.) des QTabDialog-Widget und Verknüpfen der einzelnen Button-Signale mit den entsprechenden Slotroutinen. Wichtige Methoden, die die Klasse QTabDialog anbietet, sind: addtab(qwidget *child, const QString& label): fügt eine neue Seite (child) zu einem QTabDialog-Widget hinzu. label ist dabei die Beschriftung dieser Seite, die in der immer sichtbaren Tableiste für diese Seite (in Button-Form) angezeigt wird. Ein Klick auf diese Beschriftung bringt dann diese Seite in den Vordergrund. Innerhalb des Beschriftungstextes kann dabei ein Beschleuniger angegeben werden, indem dem entsprechenden Zeichen & vorangestellt wird, um so dem Benutzer eine schnelle Anwahl dieser Seite mittels Eingabe des entsprechenden Zeichens bei gedrückter Alt -Taste zu ermöglichen. 446

82 6.6 Klasse QTabDialog zur Stapelung von Widgets im Karteikartenformat Es ist darauf hinzuweisen, dass eine Seite in jedem Fall mit addtab() bzw. inserttab() in einem QTabDialog-Widget hinzuzufügen ist. Die alleinige Angabe des QTabDialog-Widget als Elternwidget bei der Erzeugung einer QWidget-Objekts (für eine Seite) reicht nicht aus. Eine solche Seite würde nicht im QTabDialog-Widget eingeordnet und damit auch nicht angezeigt. inserttab(qwidget *child, const QString& label, int index=- 1): entspricht der Methode addtab(), nur dass man hier eine Position (index) angeben kann, an der die entsprechende Seite einzufügen ist. Die Voreinstellung (index=-1) bedeutet, dass die entsprechende Seite am Ende eingefügt wird, wie dies auch bei addtab() geschieht. changetab(qwidget *w, const QString& label): legt eine neue Beschriftung (label) für die Seite w fest. setokbutton() setokbutton(const QString& text): Beide Methoden fügen einen Ok- Button in jeder Seite des QTabDialog-Widget unten ein, wobei bei der zweiten Methode dieser Button nicht den Text Ok, sondern den hier angegebenen text enthält. Ist text ein null-string, wird kein Ok-Button eingeblendet. Wird der Ok-Button angeklickt, wird automatisch das Signal applybuttonpressed() geschickt, und die aktuellen Einstellungen aller Seiten des QTabDialog-Widget werden übernommen. Anschließend wird dann das QTabDialog-Widget ausgeblendet. setapplybutton() setapplybutton(const QString& text): Beide Methoden fügen einen Apply-Button in jeder Seite des QTabDialog-Widget unten ein, wobei jedoch bei der zweiten Methode dieser Button nicht den Text Apply, sondern eben den hier angegebenen text enthält. Wird der Apply-Button geklickt, wird automatisch das Signal applybuttonpressed() geschickt, und die aktuellen Einstellungen aller Seiten des QTabDialog-Widget werden übernommen. Anders als beim Anklicken des Ok-Button bleibt hier das QTabDialog-Widget sichtbar und wird nicht ausgeblendet. setcancelbutton() setcancelbutton(const QString& text): Beide Methoden fügen einen Cancel-Button in jeder Seite des QTabDialog-Widgets unten ein, wobei jedoch bei der zweiten Methode dieser Button nicht den Text Cancel, sondern eben den hier angegebenen text enthält. Ist text ein null-string, wird kein Cancel- Button eingeblendet. Bei einem Klick auf den Cancel-Button wird automatisch das Signal cancelbuttonpressed() geschickt, und die Einstellungen aller Seiten des QTabDialog-Widget werden in die Zustände zurückgesetzt, die vorlagen, als das QTabDialog-Widget eingeblendet wurde, bzw. in die Zustände, die mit dem letzten Klicken des Apply-Button eingestellt wurden. Anschließend wird dann das QTabDialog-Widget ausgeblendet. setdefaultbutton() setdefaultbutton(const QString& text): Beide Methoden fügen einen Defaults-Button in jeder Seite des QTabDialog-Widget unten ein, wobei jedoch bei der zweiten Methode dieser Button nicht den Text Defaults, sondern den hier angegebenen text enthält. Ist text ein null-string, wird kein Defaults-Button 447

83 6 Vordefinierte Dialogfenster eingeblendet. Wird der Defaults-Button geklickt, wird automatisch das Signal defaultbuttonpressed() geschickt, und die Einstellungen aller Seiten des QTabDialog-Widget sollten auf ihre Defaults (Voreinstellungen) zurückgesetzt werden. Wichtig ist hierbei, dass lediglich die Einstellungen im QTabDialog- Widget zurückgesetzt werden sollten, diese aber noch nicht in der entsprechenden Anwendung übernommen werden sollten. Zum Übernehmen der vorgenommenen Einstellungen in der jeweiligen Applikation dienen der Ok- und Apply-Button, welche beide das Signal applybuttonpressed() schicken. sethelpbutton() sethelpbutton(const QString& text): Beide Methoden fügen einen Help- Button in jeder Seite des QTabDialog-Widget unten ein, wobei jedoch bei der zweiten Methode der Buttontext nicht Help, sondern der angegebene text ist. Ist text ein null-string, wird kein Help-Button eingeblendet. Wird der Help-Button geklickt, wird das Signal helpbuttonpressed() geschickt, das mit einer Slotroutine verbunden werden sollte, die entsprechende Help-Information einblendet. showpage(qwidget *w): bringt Seite w des QTabDialog-Widgets in den Vordergrund, so dass sie sichtbar wird. Diese Methode kann bei der Verwendung von Beschleunigern (in der Tableiste) sehr nützlich sein. settabenabled(qwidget *w, bool enable): schaltet die Anwahlmöglichkeit der Seite w im QTabDialog-Widget ein (enable=true) bzw. aus (enable=false). Ist die Anwahl einer Seite ausgeschaltet, so wird deren Button in der Tableiste entsprechend blass dargestellt, um dem Benutzer anzuzeigen, dass er diese Seite nicht anwählen kann. QString tablabel(qwidget *w): liefert die Beschriftung (in der Tableiste) der Seite w. settabbar(qtabbar *tb) protected: ändert den Stil der Tableiste. Diese Methode muss dabei unbedingt aufgerufen werden, bevor irgendwelche Seiten zum QTabDialog-Widget hinzugefügt werden. Zum Ändern des Aussehens der Tableiste muss dabei z. B. folgender Codeausschnitt verwendet werden: QTabBar *tb = new QTabBar( this ); //... Verschiedene Stilarten (in folg. 4 Zeilen ein // entfernen) // tb->setshape( QTabBar::RoundedAbove ); // tb->setshape( QTabBar::RoundedBelow ); // tb->setshape( QTabBar::TriangularAbove ); // tb->setshape( QTabBar::TriangularBelow ); settabbar( tb ); Tiefergehende Informationen können Interessierte in der Qt-Online-Dokumentation bei der Klasse QTabBar nachschlagen Die Signale, die die Klasse QTabDialog anbietet, sind: applybuttonpressed() signal: wird geschickt, wenn der Apply- oder Ok- Button geklickt wird; siehe dazu auch die Beschreibung der Methoden setok- Button() und setapplybutton(). Dieses Signal sollte mit einer oder auch mehreren Slotroutinen verbunden werden, die die entsprechenden Einstellungen des QTabDialog-Widgets in die entsprechende Applikation übernehmen. 448

84 6.6 Klasse QTabDialog zur Stapelung von Widgets im Karteikartenformat cancelbuttonpressed() signal: wird geschickt, wenn der Cancel-Button geklickt wird; siehe dazu auch die Beschreibung der Methode setcancelbutton(). Dieses Signal ist automatisch mit der Methode QDialog::reject() verbunden, welche das QTabDialog-Widget ausblendet. Da dieses Signal andeutet, dass alle vorgenommen Änderungen in den Einstellungen zu verwerfen sind, sollten die entsprechenden Einstellungen auch nicht in der Applikation übernommen werden. defaultbuttonpressed() signal: wird geschickt, wenn der Defaults-Button geklickt wird; siehe dazu auch die Beschreibung der Methode setdefaultbutton(). helpbuttonpressed() signal: wird geschickt, wenn der Help-Button geklickt wird; siehe dazu auch die Beschreibung der Methode sethelpbutton(). abouttoshow() signal: wird geschickt, bevor ein QTabDialog-Widget eingeblendet wird. Dieses Signal kann sinnvoll eingestezt werden, wenn man ein QTabDialog-Widget nur einmal erzeugt, und immer bei Bedarf einblendet, und ansonsten versteckt im Hintergrund hält. currentchanged(qwidget *w) signal: wird geschickt, wenn eine neue Seite sichtbar gemacht wird. Beispiel: Demonstrationsprogramm zur Klasse QTabDialog Programm 6.6 blendet ein Hauptfenster mit zwei Buttons ein, zwischen denen ein Label eingeschoben ist, das die aktuellen Einstellungen (Beantwortung der Fragen mit entsprechender Bewertung) anzeigt (siehe Abbildung 6.18). Dieses Programm erzeugt ein QTabDialog-Widget, das es immer bei einem Klick auf den Button TabDialog einblendet. Dieses QTabDialog-Widget enthält auf den ersten beiden Seiten einen kleinen Wissenstest: Auf Seite 1 eine Frage zum Allgemeinwissen (siehe links in Abbildung 6.19) und auf Seite 2 zwei Fragen zur Mathematik (siehe rechts in Abbildung 6.19). Klickt der Benutzer auf den Übernehmen-Button, wird seine Antwort ausgewertet und ihm im Label des Hauptfensters die Bewertung seiner Auswahl (richtig oder falsch) angezeigt. Auf der dritten Seite bietet dieses Abbildung 6.18: Hauptfenster des Programms

85 6 Vordefinierte Dialogfenster Abbildung 6.19: Seite 1 und Seite 2 des QTabDialog-Widgets im Programm 6.6 QTabDialog-Widget einen Button Farbauswahl an, der bei einem Klick ein QColorDialog-Widget (siehe z. B. Abbildung 6.3) einblendet, in dem der Benutzer sich eine Farbe auswählen kann, welche dann in einem Label unter diesem Button (sie- Abbildung 6.20: Seite 3 des QTabDialog-Widgets im Programm

86 6.6 Klasse QTabDialog zur Stapelung von Widgets im Karteikartenformat he Abbildung 6.20) angezeigt wird. Bei einem Klick auf den Button Übernehmen wird diese Farbe in dem Label des Hauptfensters als Hintergrundfarbe verwendet. In allen drei Seiten haben die einzelnen unten angezeigten Buttons die gleichen Auswirkungen: Ok: Die aktuellen Einstellungen aus allen drei Seiten werden übernommen und ausgewertet. Anschließend wird das QTabDialog-Widget ausgeblendet. Voreinstellung: Alle drei Seiten werden auf ihre Voreinstellungen zurückgesetzt Übernehmen: Die aktuellen Einstellungen aus allen drei Seiten werden übernommen, ohne dass das QTabDialog-Widget ausgeblendet wird. Abbrechen: Das QTabDialog-Widget wird ausgeblendet, ohne dass die vorgenommenen Einstellungen übernommen werden. Programm 6.6 tabdialog.cpp: Demoprogramm zur Klasse QTabDialog #include <qapplication.h> #include <qvbox.h> #include <qlabel.h> #include <qlineedit.h> #include <qbuttongroup.h> #include <qradiobutton.h> #include <qlistbox.h> #include <qtabdialog.h> #include <qtabbar.h> #include <qpushbutton.h> #include <qcolordialog.h> QString staedte[] = { "Sydney", "Portland", "Austra-City", "Melbourne", "New London", "Manchester", "Kapstadt", "Canberra", "Jail-City", "Koala-Town", "Suncity", "Downunder-City" ; const uint staedte_zahl = sizeof(staedte) / sizeof(staedte[0]); QString viertel_text[] = { "250000", " ", " ", "400000", " " ; const uint viertel_zahl = sizeof(viertel_text) / sizeof(viertel_text[0]); //... Klasse TabDialog class TabDialog : public QTabDialog { Q_OBJECT public: TabDialog( QString h, QString v, QString p, QColor f, QWidget *parent = 0, const char *name = 0 ) : QTabDialog( parent, name ) { //... Zum Aendern des Stils der Tableiste (in folg. Zeile // entfernen) // QTabBar *tb = new QTabBar( this ); //... Verschiedene Stilarten (in folg. 4 Zeilen ein // entfernen) // tb->setshape( QTabBar::RoundedAbove ); // tb->setshape( QTabBar::RoundedBelow ); // tb->setshape( QTabBar::TriangularAbove ); // tb->setshape( QTabBar::TriangularBelow ); //... Zum Aendern des Stils der Tableiste (in folg. Zeile // entfernen) 451

87 6 Vordefinierte Dialogfenster // settabbar( tb ); hauptstadt = h; viertel = v; preis = p; farbe = f; setuptab1(); setuptab2(); setuptab3(); setzealt(); setapplybutton( "Übernehmen" ); setokbutton(); setcancelbutton( "Abbrechen" ); setdefaultbutton( "Voreinstellung" ); connect( this, SIGNAL( applybuttonpressed() ), SLOT( setzeuebernehmen() ) ); connect( this, SIGNAL( defaultbuttonpressed() ), SLOT( setzedefault() ) ); QString gethauptstadt() { return hauptstadt; QString getviertel() { return viertel; QString getpreis() { return preis; QColor getfarbe() { return farbe; signals: void neuuebernommen(); private slots: void setzeuebernehmen() { //... setzeuebernehmen uint i; hauptstadt = viertel = ""; for (i=0; i<cities->count(); i++) if ( cities->isselected( i ) ) hauptstadt = cities->text( i ); for (i=0; i<viertel_zahl; i++) if ( frage2a[i]->ischecked() ) viertel = frage2a[i]->text(); preis = frage2b->text(); farbe = neufarbe; emit neuuebernommen(); void setzedefault() { //... setzedefault uint i; cities->clear(); for ( i = 0; i < staedte_zahl; i++ ) cities->insertitem( staedte[i], i ); for ( i=0; i<viertel_zahl; i++) frage2a[i]->setchecked( false ); frage2b->settext( "" ); farbanzeige->setpalette( QPalette( neufarbe=qt::white, Qt::white ) ); void neuefarbe() { //... neuefarbe QColor f = QColorDialog::getColor( neufarbe, 0 ); if ( f.isvalid() ) farbanzeige->setpalette( QPalette( neufarbe = f, f ) ); private: QListBox *cities; QRadioButton *frage2a[viertel_zahl]; QLineEdit *frage2b; 452

88 6.6 Klasse QTabDialog zur Stapelung von Widgets im Karteikartenformat QLabel QPushButton QString QColor *farbanzeige; *farbbutton; hauptstadt, viertel, preis; farbe, neufarbe; void setuptab1(); void setuptab2(); void setuptab3(); void setzealt() { //... setzealt uint i; for ( i=0; i < cities->count(); i++ ) cities->setselected( i, cities->text(i) == hauptstadt ); for ( i=0; i<viertel_zahl; i++) frage2a[i]->setchecked( viertel == frage2a[i]->text() ); frage2b->settext( preis ); farbanzeige->setpalette( QPalette( neufarbe = farbe, farbe ) ); ; //... setuptab1 void TabDialog::setupTab1() { QVBox *tab1 = new QVBox( this ); tab1->setmargin( 5 ); tab1->setspacing( 5 ); QLabel *l = new QLabel( "Wie heisst die Hauptstadt von Australien?", tab1 ); l->setbackgroundcolor( Qt::yellow ); cities = new QListBox( tab1 ); for ( uint i = 0; i < staedte_zahl; i++ ) cities->insertitem( staedte[i], i ); cities->setpalette( QPalette( Qt::green, Qt::green ) ); addtab( tab1, "Allgemeinwissen" ); //... setuptab2 void TabDialog::setupTab2() { QVBox *tab2 = new QVBox( this ); tab2->setmargin( 5 ); tab2->setspacing( 5 ); QButtonGroup *bg = new QButtonGroup( 1, QGroupBox::Horizontal, "Wieviel ist eine Million geteilt durch ein Viertel?", tab2 ); for (uint i=0; i<viertel_zahl; i++) { frage2a[i] = new QRadioButton( viertel_text[i], bg ); frage2a[i]->setbackgroundcolor( Qt::green.light( 180 ) ); bg->setbackgroundcolor( Qt::green.light( 180 ) ); bg->setminimumheight( 200 ); QLabel *l = new QLabel( tab2 ); l->settext( "Eine Flasche Wein kostet zehn Euro,\n" "Der Wein kostet acht Euro mehr als die Flasche.\n" "Wie teuer ist die Flasche?" ); l->setbackgroundcolor( Qt::yellow ); 453

89 6 Vordefinierte Dialogfenster frage2b = new QLineEdit( tab2 ); addtab( tab2, "Mathematik" ); //... setuptab3 void TabDialog::setupTab3() { QVBox *tab3 = new QVBox( this ); tab3->setmargin( 50 ); tab3->setspacing( 30 ); farbbutton = new QPushButton( "Farbauswahl", tab3 ); connect( farbbutton, SIGNAL( clicked() ), SLOT( neuefarbe() ) ); farbanzeige = new QLabel( tab3 ); addtab( tab3, "Farben" ); //... Klasse MyWidget class MyWidget : public QVBox { Q_OBJECT public: MyWidget() : QVBox( 0, 0 ) { QPushButton *b1 = new QPushButton( "TabDialog", this); b1->setpalette( QPalette( Qt::green, Qt::green ) ); hauptstadt = viertel = preis = ""; farbe = Qt::white; auswahlanzeige = new QLabel( this ); QString s; s.sprintf( " Hauptstadt: %s\n" " Eine Million geteilt durch ein Viertel: %s\n" " Preis der Flasche: %s\n" " Farbe (siehe Hintergrund)\n", (const char *)hauptstadt, (const char *)viertel, (const char *)preis ); auswahlanzeige->settext( s ); auswahlanzeige->setpalette( QPalette( farbe, farbe ) ); auswahlanzeige->resize( auswahlanzeige->sizehint() ); auswahlanzeige->setfixedsize( 400, 200 ); auswahlanzeige->show(); QPushButton *b2 = new QPushButton( "Beenden", this); b2->setpalette( QPalette( Qt::red, Qt::red ) ); connect( b1, SIGNAL( clicked() ), this, SLOT( showtabdialog() ) ); connect( b2, SIGNAL( clicked() ), qapp, SLOT( quit() ) ); private slots: void neuanzeige() { QString s; hauptstadt = tabdialog->gethauptstadt(); viertel = tabdialog->getviertel(); preis = tabdialog->getpreis(); farbe = tabdialog->getfarbe(); s.sprintf( " Hauptstadt: %s (%s)\n" " Eine Million geteilt durch ein Viertel: %s (%s)\n" " Preis der Flasche: %s (%s)\n" " Farbe (siehe Hintergrund)\n", 454

90 6.6 Klasse QTabDialog zur Stapelung von Widgets im Karteikartenformat (const char *)hauptstadt, (hauptstadt=="canberra")? "Richtig" : "Falsch", (const char *)viertel, (viertel==" ")? "Richtig" : "Falsch", (const char *)preis, (preis=="1")? "Richtig" : "Falsch" ); auswahlanzeige->settext( s ); auswahlanzeige->setpalette( QPalette( farbe, farbe ) ); repaint(); void showtabdialog() { private: ; tabdialog = new TabDialog( hauptstadt, viertel, preis, farbe ); tabdialog->resize( 450, 500 ); tabdialog->setcaption( "Wissenstest mit Farbenwahl" ); tabdialog->show(); connect( tabdialog, SIGNAL( neuuebernommen() ), TabDialog *tabdialog; QLabel QString QColor this, SLOT( neuanzeige() ) ); *auswahlanzeige; hauptstadt, viertel, preis; farbe; //... main int main( int argc, char *argv[] ) { QApplication a( argc, argv ); MyWidget *w = new MyWidget; w->resize( 200, 100 ); w->show(); a.setmainwidget( w ); return a.exec(); #include "tabdialog.moc" Abbildung 6.21: Seite 1 zur Eingabe des Namens und der Adresse 455

91 Index Symbole Überlappendes Layout Übung ampeltimer.cpp autofahr.cpp bildflow.cpp canvas2.cpp clipboardsend.cpp clipping2.cpp colordialog2.cpp. 423 countrydate.cpp cursor2.cpp customevent3.cpp. 867 datapump2.cpp datastream2.cpp dezahexa.cpp dialog2.cpp domplot2.cpp dragdropcards.cpp dualstack.cpp dynfokus.cpp dynlayout.cpp dynvalidator.cpp. 799 editor.cpp ehe.cpp eventfilter2.cpp. 858 filebytes.cpp filedialog2.cpp flywindow.cpp fontdialog2.cpp frame2.cpp functionplot2.cpp glpyramide.cpp graphik2.cpp graphik2.h groupbox2.cpp httpd3.cpp image2.cpp inputdialog2.cpp. 483 josephus.cpp lcdwandel2.cpp life.cpp linkreis.cpp listbox.cpp listview2.cpp logging.cpp lspin.cpp manntisch.cpp mastermind.cpp meinls.cpp menues2.cpp messagebox2.cpp movieframes.cpp multidownload.cpp multtable.cpp nsbillard.cpp ostern.cpp paintstack.cpp penfill.cpp perl_listspin perl_malprog coverview.cpp pointarray2.cpp printbild2.cpp progressbar2.cpp. 300 progressdialog2.cpp pythagoras.cpp queue.cpp queue2.cpp radioadd.cpp regexp4.cpp restaurant.cpp scrollview2.cpp sendevent2.cpp snapshot2.cpp sound2.cpp splitter2.cpp tabdialog2.cpp timeprogress.cpp. 628 togglebutton.cpp. 216 virtfrank.cpp waldbrand.cpp wellen.cpp widgetstack2.cpp. 373 wizard2.cpp woist.cpp woistmaus.cpp worktime.cpp xmlplot2.cpp xref.cpp zeilzeich.cpp zeilzeich2.cpp zweirect.cpp A Animation , 775 ASSERT Makro Austritts-Events Auswahlwidgets B Balloon help Bedingungs-Variablen Benutzerdefinierte Events Benutzerdefiniertes Layout. 398 Beschleuniger Bildformate Browser Directory Bubble help Buttongruppe Buttons C C << >>

92 Index Überladen von Funktionen 18 Zeilen-Kommentar //.16 Abstrakte Klassen cerr cin clog cout Default-Argumente delete Destruktor Frühe Bindung friend Function overloading.. 18 Inline-Funktionen Klassen Mehrfachvererbung Methoden new Nicht-objektorientierte Erweiterungen operator Operator overloading.. 65 Polymorphismus private protected public Referenz-Operator & Späte Bindung Strukturen Template- Funktionen Klassen this C++ Variablen-Deklarationen 16 Vererbung Virtuelle Basisklassen Methoden CHECK_PTR Makro Clipboard mit Drag-and-Drop Clipping (Graphik) Close-Events ColorRole Typ connect() connect() Containerklasse QList Hashtabelle Listen QArray QAsciiCache QAsciiDict QBitArray QByteArray QCache QDict QIntCache QIntDict QMap QPointArray QPtrDict QQueue QStack QStrIList QStringList QStrList QValueList QValueStack QVector Containerklassen critical() Cursorformen , 754 D Danksagung..... VII Data-Sharing Dateiauswahl-Dialogbox 424 Dateioperationen Datenstruktur QList FIFO Hashtabelle LIFO Listen QArray QAsciiCache QAsciiDict QBitArray QByteArray QCache QDict QIntCache QIntDict QMap QPointArray QPtrDict QQueue QStack Queue QValueList QValueStack QVector Stack Warteschlange Datenstrukturen Datentypen Datum Datum und Zeit Debugging deep copy-sharing Dialogbox Dateiauswahl Drucker Einfache Eingabe Farbe Font Fortschrittsanzeige , 483 Karteikarten Kombobox-Eingabe Message Mitteilungen Nachrichten Tabdialog Texteingabe Wizards Zahleneingabe Dialogfenster Directorybrowser Directoryoperationen.. 485, 513 Dokumentation DOM-Schnittstelle Doppel-Pufferung Drag-and-Drop MIME-Typen mit Clipboard Drag-Events , 854 Drehknopf Drop-Events , 854 Druckerdialog Druckerinformationen dumpobjectinfo Funktion 959 dumpobjecttree Funktion 959 Dynamisch änderndes Layout E E/A-Geräte Ebuilder Editor einzeilig mehrzeilig Einfaches Layout Eintritts-Events Ereignisse Event Austritts Benutzerdefiniert Close Custom Drag , 854 Drop , 854

93 Index Eintritts Fokus Größenänderungs Hide Mal Maus Positionsänderungs Resize Schließ Senden Show Sichtbarkeits Subwidget Synthetisch Tastatur Timer , 840 Versteck Event-Filter , 855 Events Explizites Data-Sharing. 530 F Füllbalken einfach Fortschrittsanzeige Farb-Dialogbox Farballozierung Farbgruppen in Qt Farbmodelle in Qt Farbname QColor-Objekte vordefinierte Strings Filter (Event) , 855 findtr Tool Flache Kopie Flimmerfreie Graphik Fokus Fokus-Events Font-Dialogbox Form Cursor Format Bilder Pixmap Fortgeschrittenes Layout 377 Fortschrittsanzeige Fortschrittsanzeige Klasse Frames FTP Protokoll Funktionsplotter G Geleitwort.... V Geschachteltes Layout getopenfilename(). 197 getsavefilename(). 196 Größenänderungs-Events Graphik Clipping Doppel-Pufferung Füllmuster Flimmerfrei Geometrische Figuren 657, 670 Positionieren Rasterung Text Transformationen View-Transformationen Graphik Viewport-Transformationen 698 Graphik Window-Transformationen 692 Graphik World-Transformationen Zeichenstift Gruppenboxen GUI-Builder Ebuilder Qt-Designer QtArchitect QtEz H Hashtabellen Hauptfenster Hide-Events High-Level Events Hilfstexte HSV-Farbmodell HTML http Protokoll I Implizites Data-Sharing. 530 information() Informationswidgets Internationalisierung Iterator QAsciiCacheIterator. 562 QAsciiDictIterator QCacheIterator QDictIterator QIntCacheIterator QIntDictIterator. 557 QListIterator QMapConstIterator QMapIterator QPtrDictIterator. 557 QValueListConstIterator 575 QValueListIterator K Karteikarten Komboboxen Kompilieren Qt-Programme Konsistente Eingaben Kopie flache tiefe L Labels Laufbalken Layout Überlappend Benutzerdefiniert Dynamisch ändernd Einfach Fortgeschritten Geschachtelt Tabellenform LCD-Anzeige linguist Tool Listboxen Listenansicht Low-Level Events lrelease Tool lupdate Tool M Mainwindow make Tool , 1149 Makefile Mal-Events Maus-Events Mauscursor Mehrsprachige Applikationen Menüleiste Menüs Kontext Popup mergetr Tool Messagebox Meta Object Compiler. siehe moc 1157

94 Index MIME-Typen moc mousedoubleclickevent() 166 msg2qm Tool Mutual Exclusion N Namen von Objekten Netscape Plugins Netzwerkprogrammierung. 965 nntp Protokoll O Objektnamen Objektorientierung Attribute Basisklasse Exemplar Instanz Methode Objekt Operation Vererbung Online-Dokumentation. 117 Online-Hilfe OpenGL P Paletten in Qt PerlQt Pixmap-Format Plotter Plugins Popupmenü Positionsänderungs-Events. 845 progen Tool Programm dragdropclip.cpp. 608 alt_ea.cpp ampel.cpp ampeltimer.cpp analoguhr.cpp array.cpp array2.cpp auswahlw.cpp autofahr.cpp bildflow.cpp bildformat.cpp bildtabelle.cpp bildtabelle.h biszeit.cpp bitarray.cpp bitblt.cpp bitblt2.cpp bruch.cpp bruch.h bruchio.cpp bruchio.h bruchrec.cpp bruchtyp.cpp bruchtyp2.cpp button_gruppe.cpp 211 button_popup.cpp. 213 button_slot.cpp buttons.cpp canvas.cpp canvas.h childevent.cpp cinget.cpp cinget2.cpp cingetline.cpp cinstring.cpp clipboardimage.cpp clipboardsend.cpp clipboardtext.cpp clipping.cpp colordialog.cpp colordialog2.cpp. 423 cqueue.cpp cstack.cpp cursor.cpp customevent.cpp customevent2.cpp. 865 datapump.cpp datastream.cpp datastream2.cpp datediff.cpp datum.cpp destruktor.cpp dezahexa.cpp dial.cpp dialekt1.cpp dialog.cpp dialog2.cpp dict.cpp dict2.cpp dictiterator.cpp. 553 DigitalClock.pm digitaluhr.cpp digitaluhr2.cpp dirbrows.cpp dirbrows.h displaystdin.cpp 1008 dom1.cpp domplot.cpp doublevalidator.cpp. 798 download.cpp dragdropcards.cpp dragdropimage.cpp dragdropmime.cpp dragdroptext.cpp. 600 drawutil.cpp dualstack.cpp dumpobject.cpp dynlayout.cpp dynvalidator.cpp. 799 enterleave.cpp entferbi.cpp eventfilter.cpp farbe.cpp farbgruppe.cpp farbmenu.cpp figrotate.cpp filebytes.cpp filedialog.cpp filedialog2.cpp fileinfo.cpp filetransfer.cpp. 972 flowlayout.cpp flowlayout.h focusevent.cpp fokus1.cpp fokus2.cpp fontdialog.cpp fontdialog2.cpp frame.cpp frame2.cpp functemplate.cpp.112 functionparser.cpp functionplot.cpp. 885 functionplot.h Generierung , 1149 glbox.cpp globlok.cpp graphik.cpp graphik.h groupbox.cpp groupbox2.cpp hai.cpp hauptfenster.cpp. 268 hexd.cpp http.cpp httpd2.cpp huhn.cpp ignore.cpp image.cpp inline.cpp inputdialog.cpp inputdialog2.cpp. 483

95 Index intdict.cpp intdict2.cpp international.cpp intvalidator.cpp. 795 josephus.cpp katzmaus.cpp kehrzahl.cpp keyevent.cpp keyevent2.cpp klasstemplate.cpp kompilieren layout1.cpp layout2.cpp layout3.cpp layout4.cpp layout5.cpp layout6.cpp layout7.cpp layout8.cpp lcdwandel.cpp lightdark.cpp lineedit.cpp list.cpp listiterator.cpp. 572 listspin.cpp listview1.cpp machebi.cpp main.cpp maintextsize.cpp 1124 maintextsize2.cpp mainwindow.cpp makexmlfunction.c malprog1.cpp malprog2.cpp malprog3.cpp malprog4.cpp malprog5.cpp malprog6.cpp map.cpp mastermind.cpp mehrerb1.cpp meinls.cpp memory.cpp menues.cpp messagebox.cpp messagebox2.cpp mouseevent.cpp moveevent.cpp movies.cpp movies2.cpp mutex.cpp mutex2.cpp mymail.cpp networkprotocl.cpp neu_ea1.cpp neu_ea2.cpp neu_ea3.cpp neu_ea4.cpp noflimmer1.cpp noflimmer2.cpp noflimmer3.cpp noignore.cpp nsgifscale.cpp nsgrep.cpp nsgrep.pl nsplugin1.cpp numausg.cpp numausg2.cpp oel.cpp ostern.cpp overlayout.cpp overlayout.h overload.cpp painter.cpp painter2.cpp parser.cpp parser.h perl_dclock perllcd_wandel perltext_groes philosophen.cpp picture.cpp pointarray.cpp pointarray2.cpp poker.cpp postistda.cpp potenz.cpp printbild.cpp printbild2.cpp printer1.cpp printerinfo.cpp printtext.cpp printviel.cpp progressbar.cpp progressdialog.cpp puzzle.cpp queue.cpp queue2.cpp rahmenlayout.cpp.411 rahmenlayout.h readerwriter.cpp. 929 reaktest.cpp refarray.cpp regexp1.cpp regexp2.cpp regexp3.cpp regexp4.cpp rennen.cpp resizeevent.cpp richtext.cpp 239, 1075 schachbrett.cpp schachbrett2.cpp. 699 schieb_balk.cpp scrollbar.cpp scrollbar.h scrollview.cpp sendevent.cpp setviewport.cpp showhideclose.cpp signal.cpp signalmapper.cpp. 876 sinus.cpp sinusfunc.cpp snapshot.cpp sound.cpp spiro.cpp splitter.cpp splitter2.cpp stack.cpp stringlist.cpp strlist.cpp superhirn.cpp tabdialog.cpp tabdialog2.cpp table.cpp tableview tableview.h tausch.cpp text_groes.cpp textsizeimpl.cpp , 1131 textsizeimpl.h thread.cpp tier.cpp tier.h timeprogress.cpp. 628 tooltip.cpp tooltip2.cpp transform.cpp treesize.cpp validator.cpp valuelist.cpp valuestack.cpp virtfrank.cpp welchtag.cpp widgetstack.cpp widgetstack2.cpp. 373 wizard.cpp wizard2.cpp woist.cpp worktime.cpp

96 Index wortstat.cpp xform.cpp xml1.cpp xmlplot.cpp xmlrichtext.cpp xref.cpp zeigbild.cpp zeilzeich.cpp zeilzeich2.cpp zeitadd.cpp zoo.cpp zoo.h zwei_buttons.cpp. 124 zweirect.cpp Protokoll FTP http nntp Q QApplication Klasse. 125 QArray Klasse QAsciiCache Klasse QAsciiCacheIterator Klasse QAsciiDict Klasse QAsciiDictIterator Klasse QBitArray Klasse QBitmap Klasse QBitVal Klasse QBoxLayout Klasse QBrush Klasse QBuffer Klasse QButtonGroup Klasse. 873 QButtonGroup Klasse. 206, 363 QByteArray Klasse QCache Klasse QCacheIterator Klasse QCanvas Klasse QCanvasPolygonalItem Klasse QCanvasEllipse Klasse QCanvasItem Klasse QCanvasLine Klasse QCanvasPixmap Klasse 734 QCanvasPixmapArray Klasse QCanvasPolygon Klasse QCanvasRectangle Klasse 731 QCanvasSprite Klasse 733 QCanvasText Klasse QCanvasView Klasse QChar Klasse QCheckBox Klasse QChildEvent Klasse QClipboard Klasse QCloseEvent Klasse QColor Klasse , 639 QColor-Objekte (vordefiniert) QColorDialog Klasse. 421 QColorDrag Klasse QColorGroup Klasse QComboBox Klasse QCString Klasse QCursor Klasse QCustomEvent Klasse. 863 QDataPump Klasse QDataSink Klasse QDataSource Klasse QDataStream Klasse QDate Klasse QDateTime Klasse qdebug Funktion QDial Klasse QDialog Klasse QDict Klasse QDictIterator Klasse 552 QDir Klasse QDns Klasse QDomAttr Klasse QDomCDATASection Klasse 1066 QDomCharacterData Klasse QDomComment Klasse QDomDocument Klasse 1061 QDomDocumentFragment Klasse QDomDocumentType Klasse 1067 QDomElement Klasse QDomEntity Klasse QDomEntityReference Klasse QDomImplementation Klasse QDomNamedNodeMap Klasse 1070 QDomNode Klasse QDomNodeList Klasse 1071 QDomNotation Klasse 1069 QDomProcessingInstruction Klasse QDomText Klasse QDoubleValidator Klasse 796 QDragEnterEvent Klasse. 854 QDragEnterEvent Klasse. 607 QDragLeaveEvent Klasse. 855 QDragMoveEvent Klasse , 855 QDragObject Klasse 603 QDropEvent Klasse 607, 855 QEucJpCodec Klasse QEucKrCodec Klasse QEvent Klasse qfatal Funktion QFile Klasse QFileDialog Klasse QFileIconProvider Klasse QFileInfo Klasse QFileInfoList Klasse 516 QFileInfoListIterator Klasse QFilePreview Klasse. 427 QFocusData Klasse QFocusEvent Klasse QFont Klasse.. 127, 201, 432 QFontDialog Klasse QFontInfo Klasse QFontMetrics Klasse. 469, 534 QFrame Klasse QFtp Klasse QGbkCodec Klasse QGLContext Klasse QGLFormat Klasse QGLWidget Klasse QGrid Klasse QGridLayout Klasse QGroupBox Klasse QHBox Klasse QHBoxLayout Klasse QHeader Klasse QHideEvent Klasse QHostAddress Klasse 1008 QIconDrag Klasse. 603, 607 QIconDragItem Klasse 607 QIconSet Klasse.. 344, 534 QIconView Klasse QImage Klasse QImageDrag Klasse QImageIO Klasse QInputDialog Klasse. 477 qinstallmsghandler Funktion

97 Index QIntCache Klasse QIntCacheIterator Klasse QIntDict Klasse QIntDictIterator Klasse 557 QIntValidator Klasse 794 QIODevice Klasse QIODeviceSource Klasse QJisCodec Klasse QKeyEvent Klasse QLabel Klasse , 235 QLayoutItem Klasse.. 399, 404 QLayoutIterator Klasse. 399 QLCDNumber Klasse 129, 237 QLineEdit Klasse QList Klasse QListBox Klasse QListIterator Klasse 571 QListView Klasse QListViewItem Klasse 304 QListViewItemIterator Klasse QLocalFs Klasse qm2ts Tool QMap Klasse QMapConstIterator Klasse QMapIterator Klasse. 566 QMenuBar Klasse QMenuData Klasse. 170, 255 QMessageBox Klasse.. 171, 436 QMotifStyle Klasse QMouseEvent Klasse QMoveEvent Klasse QMovie Klasse QMultiLineEdit Klasse QMutex Klasse QNetworkOperation Klasse QNetworkProtocol Klasse 984, 990 QNPInstance Klasse QNPlugin Klasse QNPStream Klasse QNPWidget Klasse QObject Klasse QObject Klasse QPaintDeviceMetrics Klasse QPainter Klasse QPainter-Zustand Sichern Wiederherstellen QPaintEvent Klasse QPalette Klasse QPen Klasse QPicture Klasse QPixmap Klasse QPixmapCache Klasse. 751 QPoint Klasse QPointArray Klasse 543 QPopupMenu Klasse QPrinter Klasse QProgressBar Klasse. 290 QProgressDialog Klasse. 294, 483 QPtrDict Klasse QPtrDictIterator Klasse 557 QPushButton Klasse QQueue Klasse QRadioButton Klasse. 205 QRangeControl Klasse 225 QRect Klasse QRegExp Klasse QRegion Klasse QResizeEvent Klasse. 844 QRgb Klasse QScrollBar Klasse QScrollView Klasse.. 172, 312 QSemaphore Klasse QSemiModal Klasse QServerSocket Klasse 996 QShowEvent Klasse QSignal Klasse QSignalMapper Klasse 875 QSize Klasse QSjisCodec Klasse QSlider Klasse , 224 QSocket Klasse QSocketDevice Klasse 996 QSocketNotifier Klasse QSound Klasse QSpinBox Klasse QSplitter Klasse QStack Klasse QStoredDrag Klasse QStoredDrag Klasse QStrIList Klasse QString Klasse QStringList Klasse QStrList Klasse QStyle Klasse Qt-Designer Qt-Referenz QTabDialog Klasse QTable Klasse QTableItem Klasse QTableSelection Klasse. 345 QTableView Klasse QtArchitect QTextBrowser Klasse. 236 QTextCodec Klasse QTextDrag Klasse QTextStream Klasse QTextView Klasse QtEz QThread Klasse QTime Klasse QTimer Klasse QTimerEvent Klasse QTimerEvent Klasse QToolButton Klasse QToolTipGroup Klasse 271 QTranslator Klasse QTsciiCodec Klasse QUriDrag Klasse QUrl Klasse QUrlInfo Klasse QUrlOperator Klasse. 965 QValidator Klasse QValueList Klasse QValueListConstIterator Klasse QValueListIterator Klasse QValueStack Klasse QVBox Klasse QVBoxLayout Klasse QVector Klasse QWaitCondition Klasse qwarning Funktion QWhatsThis Klasse QWheelEvent Klasse QWidget Klasse QWidgetStack Klasse. 370 QWindowsStyle Klasse 203 QWizard Klasse QWMatrix Klasse QXmlAttributes Klasse QXmlContentHandler Klasse QXmlDeclHandler Klasse QXmlDefaultHandler Klasse

98 Index QXmlDTDHandler Klasse QXmlEntityResolver Klasse QXmlErrorHandler Klasse 1034 QXmlInputSource Klasse QXmlLexicalHandler Klasse QXmlLocator Klasse QXmlNameSpaceSupport Klasse QXmlParseException Klasse QXmlReader Klasse QXmlSimpleReader Klasse 1041 R Rasterung (Graphik) Referenz Reguläre Ausdrücke Resize-Events RGB-Farbmodell Richtext S SAX2-Schnittstelle Schiebebalken , 224 Schließ-Events Screenshots Scrollviews Semaphore setgeometry() setmaximumheight() 202 setmaximumsize() setminimumheight() 202 setminimumsize() setminimumwidth(). 202 setpalette() setstyle() shallow copy-sharing Show-Events Sichtbarkeits-Events Signal-Slot-Konzept , 135, 869 sizehint() Sound Spinboxen Splitter Statuszeile Strings in Qt Subwidget-Events Synthetische Events T Tabdialog Tabelle Einfach Kalkulation Komfortabel Kopf Spreadsheet Tabelle von Bildern Tastatur-Events Tastaturfokus Testausgaben Textanzeige HTML Komfortabel Richtext Textbrowser Texteingabe Threads Tiefe Kopie Timer Timer-Events , 840 tmake Tool ,1149 tmake Tool Tool Ebuilder findtr linguist lrelease lupdate make , 1149 mergetr msg2qm progen qm2ts Qt-Designer QtArchitect QtEz tmake ,120, 1149 uic Tooltips Transformationen (Graphik) 675 U uic Compiler Unicode Unified Modeling Language (UML) URI-Referenzen V Validierung von Eingaben Versteck-Events View-Transformationen (Graphik) Viewport-Transformationen (Graphik) Vordefinierte Datentypen Vordefinierte Dialogfenster. 417 Vordefinierte Datenstrukturen W warning() Werkzeugleiste Widget Begriff Widgetstack Window-Transformationen (Graphik) Wizards World-Transformationen (Graphik) X XML DOM SAX XML-Parser Z Zeichenketten in Qt Zeit Zeit und Datum Zeitschaltuhren Zuordnung von Widgets

Helmut Herold. Das Qt-Buch. Portable GUI-Programmierung unter Linux/Unix/Windows 2., überarbeitete Auflage

Helmut Herold. Das Qt-Buch. Portable GUI-Programmierung unter Linux/Unix/Windows 2., überarbeitete Auflage Helmut Herold Das Qt-Buch Portable GUI-Programmierung unter Linux/Unix/Windows 2., überarbeitete Auflage Einleitung 1 Allgemeines zu Qt 5 1.1 Was ist Qt und warum Qt? 5 1.2 Der Begriff Widget" 6 1.3 Die

Mehr

Helmut Herold. Das Qt-Buch. Portable GUI-Programmierung unter Linux/Unix/Windows. ^m o\ SuSE PRESS

Helmut Herold. Das Qt-Buch. Portable GUI-Programmierung unter Linux/Unix/Windows. ^m o\ SuSE PRESS Helmut Herold Das Qt-Buch Portable GUI-Programmierung unter Linux/Unix/Windows ^m o\ SuSE PRESS Einleitung Einführung in die Objektorientierung und C++ 1.1 Objektorientierung in der realen Welt 1.2 Objektorientierung

Mehr

L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016

L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016 L10N-Manager 3. Netzwerktreffen der Hochschulübersetzer/i nnen Mannheim 10. Mai 2016 Referentin: Dr. Kelly Neudorfer Universität Hohenheim Was wir jetzt besprechen werden ist eine Frage, mit denen viele

Mehr

Wie halte ich Ordnung auf meiner Festplatte?

Wie halte ich Ordnung auf meiner Festplatte? Wie halte ich Ordnung auf meiner Festplatte? Was hältst du von folgender Ordnung? Du hast zu Hause einen Schrank. Alles was dir im Wege ist, Zeitungen, Briefe, schmutzige Wäsche, Essensreste, Küchenabfälle,

Mehr

Produktschulung WinDachJournal

Produktschulung WinDachJournal Produktschulung WinDachJournal Codex GmbH Stand 2009 Inhaltsverzeichnis Einleitung... 3 Starten des Programms... 4 Erfassen von Notizen in WinJournal... 6 Einfügen von vorgefertigten Objekten in WinJournal...

Mehr

Windows 8.1. Grundkurs kompakt. Markus Krimm, Peter Wies 1. Ausgabe, Januar 2014. inkl. zusätzlichem Übungsanhang K-W81-G-UA

Windows 8.1. Grundkurs kompakt. Markus Krimm, Peter Wies 1. Ausgabe, Januar 2014. inkl. zusätzlichem Übungsanhang K-W81-G-UA Markus Krimm, Peter Wies 1. Ausgabe, Januar 2014 Windows 8.1 Grundkurs kompakt inkl. zusätzlichem Übungsanhang K-W81-G-UA 1.3 Der Startbildschirm Der erste Blick auf den Startbildschirm (Startseite) Nach

Mehr

Universal Gleismauer Set von SB4 mit Tauschtextur u. integrierten Gleismauerabschlüssen!

Universal Gleismauer Set von SB4 mit Tauschtextur u. integrierten Gleismauerabschlüssen! Stefan Böttner (SB4) März 2013 Universal Gleismauer Set von SB4 mit Tauschtextur u. integrierten Gleismauerabschlüssen! Verwendbar ab EEP7.5(mitPlugin5) + EEP8 + EEP9 Abmessung: (B 12m x H 12m) Die Einsatzhöhe

Mehr

Erste Schritte mit Microsoft Office 365 von Swisscom

Erste Schritte mit Microsoft Office 365 von Swisscom Inhaltsverzeichnis 1 Wichtigstes in Kürze... 2 2 Erstanmeldung bei Microsoft Office 365... 2 2.1 Basiskonfiguration... 4 2.2 Navigation in Office 365... 5 3 Nutzung von Microsoft Office 365... 6 3.1 Schreiben

Mehr

Flyer, Sharepics usw. mit LibreOffice oder OpenOffice erstellen

Flyer, Sharepics usw. mit LibreOffice oder OpenOffice erstellen Flyer, Sharepics usw. mit LibreOffice oder OpenOffice erstellen Wir wollen, dass ihr einfach für eure Ideen und Vorschläge werben könnt. Egal ob in ausgedruckten Flyern, oder in sozialen Netzwerken und

Mehr

Mediator 9 - Lernprogramm

Mediator 9 - Lernprogramm Mediator 9 - Lernprogramm Ein Lernprogramm mit Mediator erstellen Mediator 9 bietet viele Möglichkeiten, CBT-Module (Computer Based Training = Computerunterstütztes Lernen) zu erstellen, z. B. Drag & Drop

Mehr

Informatik Kurs Simulation. Hilfe für den Consideo Modeler

Informatik Kurs Simulation. Hilfe für den Consideo Modeler Hilfe für den Consideo Modeler Consideo stellt Schulen den Modeler kostenlos zur Verfügung. Wenden Sie sich an: http://consideo-modeler.de/ Der Modeler ist ein Werkzeug, das nicht für schulische Zwecke

Mehr

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren Lineargleichungssysteme: Additions-/ Subtraktionsverfahren W. Kippels 22. Februar 2014 Inhaltsverzeichnis 1 Einleitung 2 2 Lineargleichungssysteme zweiten Grades 2 3 Lineargleichungssysteme höheren als

Mehr

Stundenerfassung Version 1.8 Anleitung Arbeiten mit Replikaten

Stundenerfassung Version 1.8 Anleitung Arbeiten mit Replikaten Stundenerfassung Version 1.8 Anleitung Arbeiten mit Replikaten 2008 netcadservice GmbH netcadservice GmbH Augustinerstraße 3 D-83395 Freilassing Dieses Programm ist urheberrechtlich geschützt. Eine Weitergabe

Mehr

Handbuch Fischertechnik-Einzelteiltabelle V3.7.3

Handbuch Fischertechnik-Einzelteiltabelle V3.7.3 Handbuch Fischertechnik-Einzelteiltabelle V3.7.3 von Markus Mack Stand: Samstag, 17. April 2004 Inhaltsverzeichnis 1. Systemvorraussetzungen...3 2. Installation und Start...3 3. Anpassen der Tabelle...3

Mehr

Animationen erstellen

Animationen erstellen Animationen erstellen Unter Animation wird hier das Erscheinen oder Bewegen von Objekten Texten und Bildern verstanden Dazu wird zunächst eine neue Folie erstellt : Einfügen/ Neue Folie... Das Layout Aufzählung

Mehr

Dokumentation IBIS Monitor

Dokumentation IBIS Monitor Dokumentation IBIS Monitor Seite 1 von 16 11.01.06 Inhaltsverzeichnis 1. Allgemein 2. Installation und Programm starten 3. Programmkonfiguration 4. Aufzeichnung 4.1 Aufzeichnung mitschneiden 4.1.1 Inhalt

Mehr

Einzel-E-Mails und unpersönliche Massen-Mails versenden

Einzel-E-Mails und unpersönliche Massen-Mails versenden Einzel-E-Mails und unpersönliche Massen-Mails versenden Copyright 2012 cobra computer s brainware GmbH cobra Adress PLUS ist eingetragenes Warenzeichen der cobra computer s brainware GmbH. Andere Begriffe

Mehr

Aktualisierung zum Buch Windows und PostgreSQL

Aktualisierung zum Buch Windows und PostgreSQL Aktualisierung zum Buch Windows und PostgreSQL von Stefan Kunick Stand 16.12.2009 Seite 1 Vorwort: In der Version 8.4 hat sich nun einiges geändert. Auf einige Punkte gehe ich in diesem PDF-Dokument ein

Mehr

QTTabBar Einrichtung, ein Tutorial

QTTabBar Einrichtung, ein Tutorial QTTabBar Einrichtung, ein Tutorial Von Heiko Schulze Eines der ganz entscheidenden Dinge, das im Explorer fehlt ist das tabunterstützte Navigieren. Dafür gibt es bereits seit Jahren die QTTabBar. Sie wurde

Mehr

Einleitung. Für wen ist dieses Buch

Einleitung. Für wen ist dieses Buch i Willkommen! Dieses Buch aus der Reihe Schritt für Schritt wurde so konzipiert, dass Sie mit dem Buch leicht und einfach die wesentlichen Aspekte beim Einsatz von vier der Microsoft Office 2016- Apps

Mehr

Anleitung zur Verwendung der VVW-Word-Vorlagen

Anleitung zur Verwendung der VVW-Word-Vorlagen Anleitung zur Verwendung der VVW-Word-Vorlagen v1.0. Jun-15 1 1 Vorwort Sehr geehrte Autorinnen und Autoren, wir haben für Sie eine Dokumentenvorlage für Microsoft Word entwickelt, um Ihnen die strukturierte

Mehr

FuxMedia Programm im Netzwerk einrichten am Beispiel von Windows 7

FuxMedia Programm im Netzwerk einrichten am Beispiel von Windows 7 FuxMedia Programm im Netzwerk einrichten am Beispiel von Windows 7 Die Installation der FuxMedia Software erfolgt erst NACH Einrichtung des Netzlaufwerks! Menüleiste einblenden, falls nicht vorhanden Die

Mehr

Medea3 Print-Client (m3_print)

Medea3 Print-Client (m3_print) Medea3 Print-Client (m3_print) Installationsanleitung Installationsanleitung m3_print.exe...2 1. Installieren von Ghostskript und Ghostview...2 1. Ghostskript...2 2. Ghostview...3 2. Kopieren des Print-Client-Programms...6

Mehr

Anleitung über den Umgang mit Schildern

Anleitung über den Umgang mit Schildern Anleitung über den Umgang mit Schildern -Vorwort -Wo bekommt man Schilder? -Wo und wie speichert man die Schilder? -Wie füge ich die Schilder in meinen Track ein? -Welche Bauteile kann man noch für Schilder

Mehr

Praktikum IKT 3. Semester

Praktikum IKT 3. Semester Praktikum IKT 3. Semester Dr. Andreas Müller, TU Chemnitz, Fakultät für Informatik Inhaltsverzeichnis 1 1 Einführung in QT 1.1 Die QT-Bibliothek Informationen: http://www.trolltech.com Lehner, B: KDE-

Mehr

Lizenzen auschecken. Was ist zu tun?

Lizenzen auschecken. Was ist zu tun? Use case Lizenzen auschecken Ihr Unternehmen hat eine Netzwerk-Commuterlizenz mit beispielsweise 4 Lizenzen. Am Freitag wollen Sie Ihren Laptop mit nach Hause nehmen, um dort am Wochenende weiter zu arbeiten.

Mehr

Update VR-NetWorld-Software 3.34 PROFILWECHSEL SICHERHEITSDATEI (ALT) NACH SICHERHEITSDATEI (NEU) Anleitung nur für Versionen ab 3.34.

Update VR-NetWorld-Software 3.34 PROFILWECHSEL SICHERHEITSDATEI (ALT) NACH SICHERHEITSDATEI (NEU) Anleitung nur für Versionen ab 3.34. Update VR-NetWorld-Software 3.34 PROFILWECHSEL SICHERHEITSDATEI (ALT) NACH SICHERHEITSDATEI (NEU) Anleitung nur für Versionen ab 3.34 Für Der Empfehlung der Bundesnetzagentur und des Bundesamtes für Sicherheit

Mehr

Nicht kopieren. Der neue Report von: Stefan Ploberger. 1. Ausgabe 2003

Nicht kopieren. Der neue Report von: Stefan Ploberger. 1. Ausgabe 2003 Nicht kopieren Der neue Report von: Stefan Ploberger 1. Ausgabe 2003 Herausgeber: Verlag Ploberger & Partner 2003 by: Stefan Ploberger Verlag Ploberger & Partner, Postfach 11 46, D-82065 Baierbrunn Tel.

Mehr

ECDL Europäischer Computer Führerschein. Jan Götzelmann. 1. Ausgabe, Juni 2014 ISBN 978-3-86249-544-3

ECDL Europäischer Computer Führerschein. Jan Götzelmann. 1. Ausgabe, Juni 2014 ISBN 978-3-86249-544-3 ECDL Europäischer Computer Führerschein Jan Götzelmann 1. Ausgabe, Juni 2014 Modul Präsentation Advanced (mit Windows 8.1 und PowerPoint 2013) Syllabus 2.0 ISBN 978-3-86249-544-3 ECDLAM6-13-2 3 ECDL -

Mehr

Outlook. sysplus.ch outlook - mail-grundlagen Seite 1/8. Mail-Grundlagen. Posteingang

Outlook. sysplus.ch outlook - mail-grundlagen Seite 1/8. Mail-Grundlagen. Posteingang sysplus.ch outlook - mail-grundlagen Seite 1/8 Outlook Mail-Grundlagen Posteingang Es gibt verschiedene Möglichkeiten, um zum Posteingang zu gelangen. Man kann links im Outlook-Fenster auf die Schaltfläche

Mehr

Jederzeit Ordnung halten

Jederzeit Ordnung halten Kapitel Jederzeit Ordnung halten 6 auf Ihrem Mac In diesem Buch war bereits einige Male vom Finder die Rede. Dieses Kapitel wird sich nun ausführlich diesem so wichtigen Programm widmen. Sie werden das

Mehr

Daten-Synchronisation zwischen dem ZDV-Webmailer und Outlook (2002-2007) Zentrum für Datenverarbeitung der Universität Tübingen

Daten-Synchronisation zwischen dem ZDV-Webmailer und Outlook (2002-2007) Zentrum für Datenverarbeitung der Universität Tübingen Daten-Synchronisation zwischen dem ZDV-Webmailer und Outlook (2002-2007) Zentrum für Datenverarbeitung der Universität Tübingen Inhalt 1. Die Funambol Software... 3 2. Download und Installation... 3 3.

Mehr

Installationsanleitung Sander und Doll Mobilaufmaß. Stand 22.04.2003

Installationsanleitung Sander und Doll Mobilaufmaß. Stand 22.04.2003 Installationsanleitung Sander und Doll Mobilaufmaß Stand 22.04.2003 Sander und Doll AG Installationsanleitung Sander und Doll Mobilaufmaß Inhalt 1 Voraussetzungen...1 2 ActiveSync...1 2.1 Systemanforderungen...1

Mehr

Informationen zur Verwendung von Visual Studio und cmake

Informationen zur Verwendung von Visual Studio und cmake Inhaltsverzeichnis Informationen zur Verwendung von Visual Studio und cmake... 2 Erste Schritte mit Visual Studio... 2 Einstellungen für Visual Studio 2013... 2 Nutzung von cmake... 6 Installation von

Mehr

Vision für Mac BENUTZERHANDBUCH

Vision für Mac BENUTZERHANDBUCH Vision für Mac BENUTZERHANDBUCH Copyright 1981-2015 Netop Business Solutions A/S. Alle Rechte vorbehalten. Teile unter Lizenz Dritter. Senden Sie Ihr Feedback an: Netop Business Solutions A/S Bregnerodvej

Mehr

Schrittweise Anleitung zur Erstellung einer Angebotseite 1. In Ihrem Dashboard klicken Sie auf Neu anlegen, um eine neue Seite zu erstellen.

Schrittweise Anleitung zur Erstellung einer Angebotseite 1. In Ihrem Dashboard klicken Sie auf Neu anlegen, um eine neue Seite zu erstellen. Schrittweise Anleitung zur Erstellung einer Angebotseite 1. In Ihrem Dashboard klicken Sie auf Neu anlegen, um eine neue Seite zu erstellen. Klicken Sie auf Neu anlegen, um Ihre neue Angebotseite zu erstellen..

Mehr

Kapitel 3 Bilder farblich verändern - Arbeiten mit Objekten

Kapitel 3 Bilder farblich verändern - Arbeiten mit Objekten Nahezu auf jedem Buchcover, CD Hülle oder auf den Werbeseiten in Zeitschriften und Magazinen, sehen Sie fast ausschließlich Bilder, die mit einem EBV Programm einen sogenannten künstlerischen Touch erhalten

Mehr

Speicher in der Cloud

Speicher in der Cloud Speicher in der Cloud Kostenbremse, Sicherheitsrisiko oder Basis für die unternehmensweite Kollaboration? von Cornelius Höchel-Winter 2013 ComConsult Research GmbH, Aachen 3 SYNCHRONISATION TEUFELSZEUG

Mehr

Ein Blick voraus. des Autors von C++: Bjarne Stroustrup. 04.06.2005 Conrad Kobsch

Ein Blick voraus. des Autors von C++: Bjarne Stroustrup. 04.06.2005 Conrad Kobsch Ein Blick voraus des Autors von C++: Bjarne Stroustrup 04.06.2005 Conrad Kobsch Inhalt Einleitung Rückblick Nur eine Übergangslösung? Was würde C++ effektiver machen? Quelle 2 Einleitung Wo steht C++,

Mehr

Textgestaltung mit dem Editor TinyMCE Schritt für Schritt

Textgestaltung mit dem Editor TinyMCE Schritt für Schritt Textgestaltung mit dem Editor TinyMCE Schritt für Schritt Folgender Artikel soll veröffentlicht und mit dem Editor TinyMCE gestaltet werden: Eine große Überschrift Ein Foto Hier kommt viel Text. Hier kommt

Mehr

MORE Profile. Pass- und Lizenzverwaltungssystem. Stand: 19.02.2014 MORE Projects GmbH

MORE Profile. Pass- und Lizenzverwaltungssystem. Stand: 19.02.2014 MORE Projects GmbH MORE Profile Pass- und Lizenzverwaltungssystem erstellt von: Thorsten Schumann erreichbar unter: [email protected] Stand: MORE Projects GmbH Einführung Die in More Profile integrierte

Mehr

Zwischenablage (Bilder, Texte,...)

Zwischenablage (Bilder, Texte,...) Zwischenablage was ist das? Informationen über. die Bedeutung der Windows-Zwischenablage Kopieren und Einfügen mit der Zwischenablage Vermeiden von Fehlern beim Arbeiten mit der Zwischenablage Bei diesen

Mehr

Das sogenannte Beamen ist auch in EEP möglich ohne das Zusatzprogramm Beamer. Zwar etwas umständlicher aber es funktioniert

Das sogenannte Beamen ist auch in EEP möglich ohne das Zusatzprogramm Beamer. Zwar etwas umständlicher aber es funktioniert Beamen in EEP Das sogenannte Beamen ist auch in EEP möglich ohne das Zusatzprogramm Beamer. Zwar etwas umständlicher aber es funktioniert Zuerst musst du dir 2 Programme besorgen und zwar: Albert, das

Mehr

Installationsleitfaden kabelsafe backup professional unter MS Windows

Installationsleitfaden kabelsafe backup professional unter MS Windows Installationsleitfaden kabelsafe backup professional unter MS Windows Installationsanleitung und Schnelleinstieg kabelsafe backup professional (kabelnet-obm) unter MS Windows Als PDF herunterladen Diese

Mehr

bla bla OX App Suite Kalender und Kontakte synchronisieren mit CalDAV und CardDAV

bla bla OX App Suite Kalender und Kontakte synchronisieren mit CalDAV und CardDAV bla bla OX App Suite Kalender und Kontakte synchronisieren mit CalDAV und CardDAV OX App Suite OX App Suite: Kalender und Kontakte synchronisieren mit CalDAV und CardDAV Veröffentlicht Mittwoch, 15. Oktober

Mehr

GITS Steckbriefe 1.9 - Tutorial

GITS Steckbriefe 1.9 - Tutorial Allgemeines Die Steckbriefkomponente basiert auf der CONTACTS XTD Komponente von Kurt Banfi, welche erheblich modifiziert bzw. angepasst wurde. Zuerst war nur eine kleine Änderung der Komponente für ein

Mehr

1. Allgemein 2. 2. Speichern und Zwischenspeichern des Designs 2. 3. Auswahl der zu bearbeitenden Seite 2. 4. Text ergänzen 3. 5. Textgrösse ändern 3

1. Allgemein 2. 2. Speichern und Zwischenspeichern des Designs 2. 3. Auswahl der zu bearbeitenden Seite 2. 4. Text ergänzen 3. 5. Textgrösse ändern 3 Inhaltsverzeichnis 1. Allgemein 2 2. Speichern und Zwischenspeichern des Designs 2 3. Auswahl der zu bearbeitenden Seite 2 4. Text ergänzen 3 5. Textgrösse ändern 3 6. Schriftart ändern 3 7. Textfarbe

Mehr

Drucken aus der Anwendung

Drucken aus der Anwendung Drucken aus der Anwendung Drucken aus der Anwendung Nicht jeder Großformatdruck benötigt die volle Funktionsvielfalt von PosterJet - häufig sind es Standarddrucke wie Flussdiagramme und Organigramme die

Mehr

Ein Bild in den Text einfügen

Ein Bild in den Text einfügen Bild in einen Artikel einfügen Ein Bild in den Text einfügen Positioniert den Cursor an der Stelle im Text, egal ob bei einem Artikel oder einer WordPress-Seite, wo das Bild eingefügt werden soll. Hinter

Mehr

Gruppenrichtlinien und Softwareverteilung

Gruppenrichtlinien und Softwareverteilung Gruppenrichtlinien und Softwareverteilung Ergänzungen zur Musterlösung Bitte lesen Sie zuerst die gesamte Anleitung durch! Vorbemerkung: Die Begriffe OU (Organizational Unit) und Raum werden in der folgenden

Mehr

http://bitschmiede.com [email protected] Drucken von Webseiten Eine Anleitung, Version 1.0

http://bitschmiede.com post@bitschmiede.com Drucken von Webseiten Eine Anleitung, Version 1.0 http://bitschmiede.com [email protected] Drucken von Webseiten Eine Anleitung, Version 1.0 Drucken von Webseiten Autor: Christian Heisch Technischer Verantwortlicher für die Webseitenumsetzung bei

Mehr

Vorweg konvertieren der Dateien

Vorweg konvertieren der Dateien Inhalt Vorweg konvertieren der Dateien... 2 Menüerstellung... 3 Hintergrundbild... 4 Filmmaterial... 4 Dateien hinzufügen... 4 Menübestandteile... 5 Menü... 5 Weitere Buttons... 5 Brenne DVD... 6 Vorweg

Mehr

teamsync Kurzanleitung

teamsync Kurzanleitung 1 teamsync Kurzanleitung Version 4.0-19. November 2012 2 1 Einleitung Mit teamsync können Sie die Produkte teamspace und projectfacts mit Microsoft Outlook synchronisieren.laden Sie sich teamsync hier

Mehr

Einer Outlook-Gruppe weitere Computer hinzufügen

Einer Outlook-Gruppe weitere Computer hinzufügen Das will ich auch wissen! Kapitel 4 Einer Outlook-Gruppe weitere Computer hinzufügen Inhaltsverzeichnis Überblick über dieses Dokument... 2 Diese Kenntnisse möchten wir Ihnen vermitteln... 2 Diese Kenntnisse

Mehr

Professionelle Seminare im Bereich MS-Office

Professionelle Seminare im Bereich MS-Office Serienbrief aus Outlook heraus Schritt 1 Zuerst sollten Sie die Kontakte einblenden, damit Ihnen der Seriendruck zur Verfügung steht. Schritt 2 Danach wählen Sie bitte Gerhard Grünholz 1 Schritt 3 Es öffnet

Mehr

C++11 C++14 Kapitel Doppelseite Übungen Musterlösungen Anhang

C++11 C++14 Kapitel Doppelseite Übungen Musterlösungen Anhang Einleitung Dieses Buch wendet sich an jeden Leser, der die Programmiersprache C++ neu lernen oder vertiefen möchte, egal ob Anfänger oder fortgeschrittener C++-Programmierer. C++ ist eine weitgehend plattformunabhängige

Mehr

Installationsanleitung für das Integrity Tool zur AusweisApp Version 1.7 (Microsoft Windows) Dokumentversion 1.0

Installationsanleitung für das Integrity Tool zur AusweisApp Version 1.7 (Microsoft Windows) Dokumentversion 1.0 Installationsanleitung für das Integrity Tool zur AusweisApp Version 1.7 (Microsoft Windows) Dokumentversion 1.0 Inhaltsverzeichnis 1 Vorbemerkung 2 2 Mindestanforderungen an Ihr System 3 3 Sicherheitsmaßnahmen

Mehr

Zahlen auf einen Blick

Zahlen auf einen Blick Zahlen auf einen Blick Nicht ohne Grund heißt es: Ein Bild sagt mehr als 1000 Worte. Die meisten Menschen nehmen Informationen schneller auf und behalten diese eher, wenn sie als Schaubild dargeboten werden.

Mehr

Einführung zum Arbeiten mit Microsoft Visual C++ 2010 Express Edition

Einführung zum Arbeiten mit Microsoft Visual C++ 2010 Express Edition In den nachfolgenden Schritten finden Sie beschrieben, wie Sie in der Entwicklungsumgebung Microsoft Visual Studio 2010 eine Projektmappe, ein Projekt und einen ersten Quellcode erstellen, diesen kompilieren,

Mehr

Satzhilfen Publisher Seite Einrichten

Satzhilfen Publisher Seite Einrichten Satzhilfen Publisher Seite Einrichten Es gibt verschiedene Möglichkeiten die Seite einzurichten, wir fangen mit der normalen Version an, Seite einrichten auf Format A5 Wählen Sie zunächst Datei Seite einrichten,

Mehr

icartoon HANDBUCH COMPOSING

icartoon HANDBUCH COMPOSING icartoon HANDBUCH icartoon ermöglicht Animationen, die man auch ausspielen kann. Sie können in Filme, Bilder und Sounddateien integriert werden. icartoon basiert auf Quicktime, passend zu jeder Plattform

Mehr

So gehts Schritt-für-Schritt-Anleitung

So gehts Schritt-für-Schritt-Anleitung So gehts Schritt-für-Schritt-Anleitung Software WISO Mein Büro Thema Eigene Auswertungen, Tabellenauswertungen Version/Datum V 13.00.05.101 Über die Tabellen-Auswertungen ist es möglich eigene Auswertungen

Mehr

Einführungskurs MOODLE Themen:

Einführungskurs MOODLE Themen: Einführungskurs MOODLE Themen: Grundlegende Einstellungen Teilnehmer in einen Kurs einschreiben Konfiguration der Arbeitsunterlagen Konfiguration der Lernaktivitäten Die Einstellungen für einen Kurs erreichst

Mehr

Projektmanagement in der Spieleentwicklung

Projektmanagement in der Spieleentwicklung Projektmanagement in der Spieleentwicklung Inhalt 1. Warum brauche ich ein Projekt-Management? 2. Die Charaktere des Projektmanagement - Mastermind - Producer - Projektleiter 3. Schnittstellen definieren

Mehr

Gelassenheit gewinnen 30 Bilder für ein starkes Selbst

Gelassenheit gewinnen 30 Bilder für ein starkes Selbst Gelassenheit gewinnen 30 Bilder für ein starkes Selbst Barbara Burghardt Gelassenheit gewinnen 30 Bilder für ein starkes Selbst Wie Sie Ihren inneren Reichtum neu entdecken 2., verbesserte Auflage Barbara

Mehr

HANDBUCH PHOENIX II - DOKUMENTENVERWALTUNG

HANDBUCH PHOENIX II - DOKUMENTENVERWALTUNG it4sport GmbH HANDBUCH PHOENIX II - DOKUMENTENVERWALTUNG Stand 10.07.2014 Version 2.0 1. INHALTSVERZEICHNIS 2. Abbildungsverzeichnis... 3 3. Dokumentenumfang... 4 4. Dokumente anzeigen... 5 4.1 Dokumente

Mehr

Anleitung für die Einrichtung weiterer Endgeräte in 4SELLERS SalesControl

Anleitung für die Einrichtung weiterer Endgeräte in 4SELLERS SalesControl SALESCONTROL Anleitung für die Einrichtung weiterer Endgeräte in 4SELLERS SalesControl Version: 1.1 Stand: 04.09.2014 Die Texte und Abbildungen in diesem Leitfaden wurden mit größter Sorgfalt erarbeitet,

Mehr

Hinweise zum Übungsblatt Formatierung von Text:

Hinweise zum Übungsblatt Formatierung von Text: Hinweise zum Übungsblatt Formatierung von Text: Zu den Aufgaben 1 und 2: Als erstes markieren wir den Text den wir verändern wollen. Dazu benutzen wir die linke Maustaste. Wir positionieren den Mauszeiger

Mehr

Erstellen eines Wordpress-Blogs

Erstellen eines Wordpress-Blogs Erstellen eines Wordpress-Blogs Inhalt 1 Einen Wordpress-Blog erstellen... 3 2 Wordpress konfigurieren... 5 2.1 Wordpress-Anmeldung... 5 2.2 Sprache einstellen... 7 2.3 Einen neuen Artikel verfassen...

Mehr

Easy Share Anleitung. April 2016

Easy Share Anleitung. April 2016 Easy Share Anleitung April 2016 1 Einleitung...3 2 Website-Funktionen für den Benutzer...3 2.1 Reiter «Dateien»... 4 2.1.1 Öffnen... 4 2.1.2 Hochladen einer Datei über die Website... 5 2.1.3 Herunterladen...

Mehr

1. Einführung. 2. Alternativen zu eigenen Auswertungen. 3. Erstellen eigener Tabellen-Auswertungen

1. Einführung. 2. Alternativen zu eigenen Auswertungen. 3. Erstellen eigener Tabellen-Auswertungen 1. Einführung Über die Tabellen-Auswertungen können Sie eigene Auswertungen nach Ihren Wünschen erstellen. Diese Auswertungen werden immer anhand der aktuellen Daten aus orgamax ermittelt, Sie können also

Mehr

PocketPC.ch Review. SBSH ilauncher 3.1. Erstelldatum: 3. Dezember 2007 Letzte Änderung: 3. Dezember 2007. PocketPC.ch_Review_iLauncher.

PocketPC.ch Review. SBSH ilauncher 3.1. Erstelldatum: 3. Dezember 2007 Letzte Änderung: 3. Dezember 2007. PocketPC.ch_Review_iLauncher. PocketPC.ch Review SBSH ilauncher 3.1 Erstelldatum: 3. Dezember 2007 Letzte Änderung: 3. Dezember 2007 Autor: Dateiname: PocketPC.ch_Review_iLauncher.doc Inhaltsverzeichnis SBSH ilauncher 3.1...3 Übersicht...

Mehr

AGROPLUS Buchhaltung. Daten-Server und Sicherheitskopie. Version vom 21.10.2013b

AGROPLUS Buchhaltung. Daten-Server und Sicherheitskopie. Version vom 21.10.2013b AGROPLUS Buchhaltung Daten-Server und Sicherheitskopie Version vom 21.10.2013b 3a) Der Daten-Server Modus und der Tresor Der Daten-Server ist eine Betriebsart welche dem Nutzer eine grosse Flexibilität

Mehr

Anleitung zur Installation von Tun EMUL 12.0

Anleitung zur Installation von Tun EMUL 12.0 Anleitung zur Installation von Tun EMUL 12.0 Anleitung zur Installation von Tun EMUL 12.0... 1 1. Vorbereitung... 2 1.1 folgende Dinge müssen vor Beginn der eigentlichen Installation vorhanden sein:...

Mehr

Anlegen von Elektro-, Sanitär- und Heizungssymbolen für die Gebäudetechnik

Anlegen von Elektro-, Sanitär- und Heizungssymbolen für die Gebäudetechnik Anlegen von Elektro-, Sanitär- und Heizungssymbolen für die Gebäudetechnik TreeCAD Copyright Die Informationen in dieser Dokumentation wurden nach bestem Wissen und mit größter Sorgfalt erstellt. Dennoch

Mehr

NoClick. Eine kurze Anleitung. Kommhelp e.v. 2010. Vereinsregister. Spendenkonto kommhelp e. V. Konto 3358400 Horstweg 25

NoClick. Eine kurze Anleitung. Kommhelp e.v. 2010. Vereinsregister. Spendenkonto kommhelp e. V. Konto 3358400 Horstweg 25 Software-Beschreibung NoClick Eine kurze Anleitung Kommhelp e.v. 2010 Kontakt Telefon: +49. (0)30. 3260 2572 Vereinsregister Spendenkonto Fax: +49. (0)30. 3434 7945 beim Amtsgericht Berlin Charlottenburg

Mehr

Anleitung. Einrichtung vom HotSync Manager für den Palm 1550 bis 1800 unter Windows 7. Palm SPT 1500 / 1550 Palm SPT 1700 / 1800. Bits & Bytes Seite 1

Anleitung. Einrichtung vom HotSync Manager für den Palm 1550 bis 1800 unter Windows 7. Palm SPT 1500 / 1550 Palm SPT 1700 / 1800. Bits & Bytes Seite 1 Anleitung Einrichtung vom HotSync Manager für den Palm 1550 bis 1800 unter Windows 7 Palm SPT 1500 / 1550 Palm SPT 1700 / 1800 Bits & Bytes Seite 1 1. Palm einrichten Für die nächsten Schritte nehmen Sie

Mehr

Easy Share Anleitung Februar 2014

Easy Share Anleitung Februar 2014 Easy Share Anleitung Februar 2014 1 Einleitung... 3 2 Website-Funktionen für den Benutzer... 3 2.1 Reiter «Dateien»... 4 2.1.1 Öffnen... 4 2.1.2 Hochladen einer Datei über die Website... 5 2.1.3 Herunterladen...

Mehr

Gemeinsamer Bibliotheksverbund: Übertragung von Datenexporten für den Verbundkatalog Öffentlicher Bibliotheken

Gemeinsamer Bibliotheksverbund: Übertragung von Datenexporten für den Verbundkatalog Öffentlicher Bibliotheken Gemeinsamer Bibliotheksverbund: Übertragung von Datenexporten für den Verbundkatalog Öffentlicher Bibliotheken Mit Anleitung zur Erstellung einer FTP Verbindung unter Windows 7 Matthias Lange

Mehr

Outlook Web App 2010. Kurzanleitung. Zürich, 09. Februar 2011. Eine Dienstabteilung des Finanzdepartements

Outlook Web App 2010. Kurzanleitung. Zürich, 09. Februar 2011. Eine Dienstabteilung des Finanzdepartements Zürich, 09. Februar 2011 Eine Dienstabteilung des Finanzdepartements Seite 2 von 10 Impressum Herausgeberin Stadt Zürich Organisation und Informatik Service Betrieb KITS-Center Wilhelmstr. 10 Postfach,

Mehr

Wie Sie mit Mastern arbeiten

Wie Sie mit Mastern arbeiten Wie Sie mit Mastern arbeiten Was ist ein Master? Einer der großen Vorteile von EDV besteht darin, dass Ihnen der Rechner Arbeit abnimmt. Diesen Vorteil sollten sie nutzen, wo immer es geht. In PowerPoint

Mehr

TESTEN SIE IHR KÖNNEN UND GEWINNEN SIE!

TESTEN SIE IHR KÖNNEN UND GEWINNEN SIE! 9 TESTEN SIE IHR KÖNNEN UND GEWINNEN SIE! An den SeniorNETclub 50+ Währinger Str. 57/7 1090 Wien Und zwar gleich in doppelter Hinsicht:!"Beantworten Sie die folgenden Fragen und vertiefen Sie damit Ihr

Mehr

Kreatives Gestalten mit Flash 5.0

Kreatives Gestalten mit Flash 5.0 Kreatives Gestalten mit Flash 5.0 Animationen, Effekte und Anwendungen für das WWW Bearbeitet von Isolde Kommer 1. Auflage 2000. Buch. 444 S. Hardcover ISBN 978 3 446 21463 7 Format (B x L): 20,1 x 23,6

Mehr

Trickfilm «Hexe» mit PowerPoint PC PowerPoint 2007

Trickfilm «Hexe» mit PowerPoint PC PowerPoint 2007 PC PowerPoint 2007 Einleitung PowerPoint ist als Präsentations-Tool bekannt. Mit PowerPoint lassen sich jedoch auch kreative Arbeiten herstellen, die sich dann filmartig präsentieren. Als vorgängige Arbeit

Mehr

Tutorial Speichern. Jacqueline Roos - Riedstrasse 14, 8908 Hedingen, 044 760 22 41 [email protected] - www.forums9.ch

Tutorial Speichern. Jacqueline Roos - Riedstrasse 14, 8908 Hedingen, 044 760 22 41 jroos@hispeed.ch - www.forums9.ch Jacqueline Roos - Riedstrasse 14, 8908 Hedingen, 044 760 22 41 [email protected] - www.forums9.ch Tutorial Speichern Wer ein Fotobuch zusammenstellen möchte, der sucht oft auf dem ganzen Computer und diversen

Mehr

Qt-Projekte mit Visual Studio 2005

Qt-Projekte mit Visual Studio 2005 Qt-Projekte mit Visual Studio 2005 Benötigte Programme: Visual Studio 2005 Vollversion, Microsoft Qt 4 Open Source s. Qt 4-Installationsanleitung Tabelle 1: Benötigte Programme für die Qt-Programmierung

Mehr

Erweiterung AE WWS Lite Win: AES Security Verschlüsselung

Erweiterung AE WWS Lite Win: AES Security Verschlüsselung Erweiterung AE WWS Lite Win: AES Security Verschlüsselung Handbuch und Dokumentation Beschreibung ab Vers. 1.13.5 Am Güterbahnhof 15 D-31303 Burgdorf Tel: +49 5136 802421 Fax: +49 5136 9776368 Seite 1

Mehr

Downloadfehler in DEHSt-VPSMail. Workaround zum Umgang mit einem Downloadfehler

Downloadfehler in DEHSt-VPSMail. Workaround zum Umgang mit einem Downloadfehler Downloadfehler in DEHSt-VPSMail Workaround zum Umgang mit einem Downloadfehler Downloadfehler bremen online services GmbH & Co. KG Seite 2 Inhaltsverzeichnis Vorwort...3 1 Fehlermeldung...4 2 Fehlerbeseitigung...5

Mehr

Konfiguration von Igel ThinClients fu r den Zugriff via Netscaler Gateway auf eine Storefront/ XenDesktop 7 Umgebung

Konfiguration von Igel ThinClients fu r den Zugriff via Netscaler Gateway auf eine Storefront/ XenDesktop 7 Umgebung Konfiguration von Igel ThinClients fu r den Zugriff via Netscaler Gateway auf eine Storefront/ XenDesktop 7 Umgebung Inhalt 1. Einleitung:... 2 2. Igel ThinClient Linux OS und Zugriff aus dem LAN... 3

Mehr

Microsoft Visual Studio Community 2015

Microsoft Visual Studio Community 2015 Microsoft Visual Studio Community 2015 Visual Studio Community 2015 ist eine kostenlose IDE mit leistungsfähigen Programmier- und Entwicklungswerkzeugen für Windows, ios und Android. Sie ist für einzelne

Mehr

Datenbanken Kapitel 2

Datenbanken Kapitel 2 Datenbanken Kapitel 2 1 Eine existierende Datenbank öffnen Eine Datenbank, die mit Microsoft Access erschaffen wurde, kann mit dem gleichen Programm auch wieder geladen werden: Die einfachste Methode ist,

Mehr

Nützliche Tipps für Einsteiger

Nützliche Tipps für Einsteiger Nützliche Tipps für Einsteiger Zusätzliche Browsertabs - effizienter Arbeiten Ein nützlicher Tipp für das Arbeiten mit easysys ist das Öffnen mehrerer Browsertabs. Dies kann Ihnen einige Mausklicks ersparen.

Mehr

etutor Benutzerhandbuch XQuery Benutzerhandbuch Georg Nitsche

etutor Benutzerhandbuch XQuery Benutzerhandbuch Georg Nitsche etutor Benutzerhandbuch Benutzerhandbuch XQuery Georg Nitsche Version 1.0 Stand März 2006 Versionsverlauf: Version Autor Datum Änderungen 1.0 gn 06.03.2006 Fertigstellung der ersten Version Inhaltsverzeichnis:

Mehr

Version 1.0.00. White Paper ZS-TimeCalculation und die Zusammenarbeit mit dem iphone, ipad bzw. ipod Touch

Version 1.0.00. White Paper ZS-TimeCalculation und die Zusammenarbeit mit dem iphone, ipad bzw. ipod Touch White Paper ZS-TimeCalculation und die Zusammenarbeit mit dem iphone, ipad bzw. ipod Touch Seite 1/8 Z-Systems 2004-2011 Einführung Das iphone bzw. der ipod Touch wird von ZS-TimeCalculation mit Hilfe

Mehr

AutoCAD 2007 - Dienstprogramm zur Lizenzübertragung

AutoCAD 2007 - Dienstprogramm zur Lizenzübertragung AutoCAD 2007 - Dienstprogramm zur Lizenzübertragung Problem: Um AutoCAD abwechselnd auf mehreren Rechnern einsetzen zu können konnte man bis AutoCAD 2000 einfach den Dongle umstecken. Seit AutoCAD 2000i

Mehr

Filmpraxis: Offline-Aktivierung für Edius

Filmpraxis: Offline-Aktivierung für Edius Schritt-für-Schritt Anleitung: EDIUS FREISCHALTEN, WENN DER SCHNITT-COMPUTER KEINE INTERNET-VERBINDUNG HAT Filmpraxis: Offline-Aktivierung für Edius 2013 Autor: Dipl. Regisseur Thomas Wagner Filmpraxis

Mehr

Leitfaden zur ersten Nutzung der R FOM Portable-Version für Windows (Version 1.0)

Leitfaden zur ersten Nutzung der R FOM Portable-Version für Windows (Version 1.0) Leitfaden zur ersten Nutzung der R FOM Portable-Version für Windows (Version 1.0) Peter Koos 03. Dezember 2015 0 Inhaltsverzeichnis 1 Voraussetzung... 3 2 Hintergrundinformationen... 3 2.1 Installationsarten...

Mehr

Erstellen von x-y-diagrammen in OpenOffice.calc

Erstellen von x-y-diagrammen in OpenOffice.calc Erstellen von x-y-diagrammen in OpenOffice.calc In dieser kleinen Anleitung geht es nur darum, aus einer bestehenden Tabelle ein x-y-diagramm zu erzeugen. D.h. es müssen in der Tabelle mindestens zwei

Mehr

Globale Tastenkombinationen für Windows

Globale Tastenkombinationen für Windows Globale Tastenkombinationen für Windows 1 Es gibt zahlreiche Tastenkombinationen, die ziemlich global funktionieren. Global bedeutet in diesem Zusammenhang, dass Sie solche Tastenkombinationen fast überall

Mehr

PowerPoint: Text. Text

PowerPoint: Text. Text PowerPoint: Anders als in einem verarbeitungsprogramm steht in PowerPoint der Cursor nicht automatisch links oben auf einem Blatt in der ersten Zeile und wartet auf eingabe. kann hier vielmehr frei über

Mehr