Kapitel 10 Synthese-Übung Nun haben wir alle Programmierwerkzeuge zusammen und können das Gelernte in einer Synthese-Übung vereinigen. main() Funktion Instanzen von Klassen anlegen Dateien lesen und schreiben Arbeiten mit Containern (Listen) Grundlage ist die Übung E8.4 - Studenten-Datenbank als Konsolen-Anwendung. Neu ist die Verwendung von Qt, um eine grafische Dialog-Anwendung zu erstellen. 10.1 Programmstruktur Die Programmstruktur basiert auf der Übung E8.4 mit der main.cpp Funktion und der Klasse CStudent main.cpp student.h/cpp Die wichtigste Erweiterung der Einbettung der Übung E8.4 in die Qt Umgebung ist die Dialog-Klasse Dialog. Die Programmstruktur ist in der Abbildung 10.1 zu sehen. 85
86 KAPITEL 10 SYNTHESE-ÜBUNG 10.2 Einbindung in Qt Abbildung 10.1: Programm-Files Warum Qt? (siehe Kapitel 11) mehr als ein Kompiler Grafische Benutzerschnittstelle (GUI) Plattformunabhängigkeit (Win, Mac, Linux, Ubuntu, ) Qt Bausteine die wir benötigen (siehe Kapitel 11): E10.1: Hallo Qt E10.2: Einfache grafische Elemente E10.3: Dialoge 10.3 Qt Programmierung 10.3.1 main() Funktion Die main() Funktion kommt uns sehr bekannt vor - fast wie die von C++. Eine Besonderheit sehen wir in der QApplication.
10.3 QT PROGRAMMIERUNG 87 #include <QApplication> #include "dialog.h" int main(int argc, char *argv[]) QApplication a(argc, argv); Dialog w; w.show(); return a.exec(); Die Applikation stellt die Verbindung der Dialoganwendung mit dem Betriebssystem (OS) her (siehe Abb. 10.2) Abbildung 10.2: Programm-Files Egal welcher Datentyp (Zahlen, Container, Dialoge ) die Syntax zur Erzeugung einer entsprechenden Instanz ist in C++ immer gleich (siehe Abb. 10.3). Abbildung 10.3: Instanz der Klasse QDialog 10.3.2 Dialog Klasse Nun schauen wir uns die Deklaration der Dialog-Klasse an. class Dialog : public QDialog Q_OBJECT public:
88 KAPITEL 10 SYNTHESE-ÜBUNG Dialog(QWidget *parent = 0); ~Dialog(); private: QListWidget *listwidget; QPushButton *pushbuttonread; QLineEdit *lineeditnamefirst; QString name; QStringList names; private slots: void on_pushbuttonread_clicked(); void on_listwidget_clicked(); ; Wir haben die üblichen Verdächtigen: Konstruktor / Destruktor (public), Dialog-Elemente (private), Funktionen, die mit den Dialog-Elementen verknüpft sind (sogenannte slots). Abbildung 10.4: Konstruktor der Klasse QDialog 10.3.3 Dialog Konstruktor Der Konstruktor der Dialog-Klasse besteht aus drei Teilen (Abb. 10.4): 1. Dialog-Elemente anlegen, 2. Verbindung zwischen Dialog-Elementen und Funktionen herstellen (connect) und 3. das Layout für den Dialog designen. (Manchmal benötigen wir einen vierten Teil für das Speichermanagement (nächstes Semester))
10.3 QT PROGRAMMIERUNG 89 Dialog::Dialog(QWidget *parent) : QDialog(parent) //1 Elemente anlegen //pushbutton pushbuttonread = new QPushButton(tr("&Read DB")); //listwidget listwidget = new QListWidget(); //lineedit lineeditnamefirst = new QLineEdit(); //2 connect connect(pushbuttonread,signal(),this,slot())); connect(listwidget,signal(),this,slot()); //3 Layout QVBoxLayout *leftlayout = new QVBoxLayout; QVBoxLayout *rightlayout = new QVBoxLayout; QHBoxLayout *mainlayout = new QHBoxLayout; mainlayout->addlayout(leftlayout); mainlayout->addlayout(rightlayout); setlayout(mainlayout); Wenn der Konstruktor gelaufen ist, sehen wir folgenden Dialog auf dem Bildschirm (Abb. 10.5). Verantwortlich für die Anzeige ist die Funktion w.show(). Abbildung 10.5: Konstruktor Nun schauen wir uns einige der Dialog-Funktionen an (slots).
90 KAPITEL 10 SYNTHESE-ÜBUNG 10.3.4 Dialog Reader Die Lese-Funktion liest die Datenbank-Datei ein. Dabei verwenden wir exakt die Funktion der Übung E8.4 STDRead(). void Dialog::on_pushButtonRead_clicked() // 1 File handling // 2 Read data base STDRead(input_file); // 3 Update data list Nach dem Ausführen der Lesefunktion sehen wir den Inhalt der Datenbank- Datei (Abb. 10.6). Abbildung 10.6: Read 10.3.5 Dialog Sort void Dialog::on_pushButtonSort_clicked() // 1 Datensätze sortieren STDSort(); // 2 Aktualisierung des Listen-Elements listwidget->clear(); //?
10.3 QT PROGRAMMIERUNG 91 names.clear(); CStudent* m_std = NULL; string name_s; for(int i=0;i<(int)std_vector.size();i++) m_std = std_vector[i]; name_s = m_std->name_first + " " + m_std->name_last; name = name_s.data(); names << name; for (int row = 0; row < names.size(); ++row) listwidget->additem(names[row]); Nach dem Ausführen der Sortier-Funktion sehen wir die Datenbank-Einträge alphabetisch sortiert (Abb. 10.7). Das war s für dieses Semester. Abbildung 10.7: Sort