Qt-Programmierung Teil 2
Jetzt existiert zwar ein neues Widget. aber damit man es sinnvoll verwenden kann. muss man sich hiervon noch eine eigene Klasse ableiten. In diesem Beispiel wird von CHelloWorldWindow die Klasse CHelloWorld abgeleitet und der virtuelle Slot showGreeting() wird implementiert. Einen eigenen Konstruktor muss man nicht schreiben, es reicht, den Konstruktor der Vaterklasse aufzurufen, da dort bereits alle Widgets initialisiert werden.
Das Hauptprogramm
kompletter Quellcode der Programmbeispiele
Im Hauptprogramm hat sich nicht besonders viel geändert.
<font color="#804040"> 1</font> <font color="#a020f0">#include </font><font color="#ff00ff"><qapplication.h></font> <font color="#0000ff">// QApplication</font>
<font color="#804040"> 2</font> <font color="#a020f0">#include </font><font color="#ff00ff">"chelloworld.h"</font> <font color="#0000ff">// CHelloWorld</font>
<font color="#804040"> 3</font>
<font color="#804040"> 4</font> <font color="#2e8b57"><strong>int</strong></font> main(<font color="#2e8b57"><strong>int</strong></font> argc, <font color="#2e8b57"><strong>char</strong></font> **argv)
<font color="#804040"> 5</font> {
<font color="#804040"> 6</font> QApplication app(argc, argv);
<font color="#804040"> 7</font>
<font color="#804040"> 8</font> <font color="#0000ff">// Create a CHelloWorld object</font>
<font color="#804040"> 9</font> CHelloWorld *window = <font color="#804040"><strong>new</strong></font> CHelloWorld();
<font color="#804040">10</font>
<font color="#804040">11</font> <font color="#0000ff">// Main window = CHelloWorld object</font>
<font color="#804040">12</font> app.setMainWidget(window);
<font color="#804040">13</font>
<font color="#804040">14</font> <font color="#0000ff">// Show the window</font>
<font color="#804040">15</font> window->show();
<font color="#804040">16</font>
<font color="#804040">17</font> <font color="#0000ff">// Go to the main loop</font>
<font color="#804040">18</font> <font color="#804040"><strong>return</strong></font> app.exec();
<font color="#804040">19</font> }
|
| Listing 1: main.cpp |
CHelloWorld: Header
Der Header kann fast direkt von CHelloWorldWindow übernommen werden, wie er vom uic generiert wird. Die einzige Anpassung ist, dass der in der Klasse CHelloWorldWindow noch virtuelle Slot public slot showGreeting() hier implementiert wird und nicht mehr virtuell ist.
Sobald man in einer Klasse ein Signal oder Slot definiert, muss auch das Makro Q_OBJECT angegeben werden, damit das ganze noch korrekt durch den Qt MetaObjectCompiler (moc) bearbeitet wird (dies geschieht automatisch durch das von TMake generierte Makefile).
<font color="#804040"> 1</font> <font color="#a020f0">#ifndef CHELLOWORLD_H</font>
<font color="#804040"> 2</font> <font color="#a020f0">#define CHELLOWORLD_H</font>
<font color="#804040"> 3</font>
<font color="#804040"> 4</font> <font color="#a020f0">#include </font><font color="#ff00ff">"CHelloWorldWindow.h"</font> <font color="#0000ff">// CHelloWorldWindow</font>
<font color="#804040"> 5</font>
<font color="#804040"> 6</font> <font color="#2e8b57"><strong>class</strong></font> CHelloWorld : <font color="#804040"><strong>public</strong></font> CHelloWorldWindow
<font color="#804040"> 7</font> {
<font color="#804040"> 8</font> <font color="#0000ff">// Q_OBJECT macro - only needed if signals or slots are defined</font>
<font color="#804040"> 9</font> Q_OBJECT
<font color="#804040">10</font>
<font color="#804040">11</font> <font color="#804040"><strong>public</strong></font>:
<font color="#804040">12</font> CHelloWorld( QWidget* parent = <font color="#ff00ff">0</font>, <font color="#2e8b57"><strong>const</strong></font> <font color="#2e8b57"><strong>char</strong></font>* name = <font color="#ff00ff">0</font>, WFlags fl = <font color="#ff00ff">0</font> );
<font color="#804040">13</font> ~CHelloWorld();
<font color="#804040">14</font>
<font color="#804040">15</font> <font color="#804040"><strong>public</strong></font> slots:
<font color="#804040">16</font> <font color="#2e8b57"><strong>void</strong></font> showGreeting();
<font color="#804040">17</font> };
<font color="#804040">18</font>
<font color="#804040">19</font> <font color="#a020f0">#endif</font> <font color="#0000ff">// CHELLOWORLD_H</font>
|
| Listing 2: chelloworld.h |
CHelloWorld: Implementierung
Bei der Implementierung der abgeleiteten Klasse beschränken sich die Arbeiten auf die Funktion showGreeting().
War die Slot-Funktion showGreeting() in der Vaterklasse CHelloWorldWindow noch virtuell, so wird sie hier endlich implementiert. Diese Slot-Funktion soll, wenn der QPushButton gedrückt wird, eine Begrüßung in einer MessageBox ausgeben. Für die MessageBox ist der Header qmessagebox.h notwendig.
Der in der MessageBox angezeigte Text wird als QString abgelegt, so dass hier noch ein weiterer Header inkludiert werden muss; diesmal ist es qstring.h.
<font color="#804040"> 1</font> <font color="#a020f0">#ifndef CHELLOWORLD_H</font>
<font color="#804040"> 2</font> <font color="#a020f0"># include </font><font color="#ff00ff">"chelloworld.h"</font>
<font color="#804040"> 3</font> <font color="#a020f0">#endif</font>
<font color="#804040"> 4</font>
<font color="#804040"> 5</font> <font color="#a020f0">#include </font><font color="#ff00ff"><qlineedit.h></font> <font color="#0000ff">// QLineEdit</font>
<font color="#804040"> 6</font> <font color="#a020f0">#include </font><font color="#ff00ff"><qmessagebox.h></font> <font color="#0000ff">// QMessageBox</font>
<font color="#804040"> 7</font> <font color="#a020f0">#include </font><font color="#ff00ff"><qradiobutton.h></font> <font color="#0000ff">// QRadioButton</font>
<font color="#804040"> 8</font> <font color="#a020f0">#include </font><font color="#ff00ff"><qstring.h></font> <font color="#0000ff">// QString</font>
<font color="#804040"> 9</font>
<font color="#804040">10</font> CHelloWorld::CHelloWorld( QWidget* parent, <font color="#2e8b57"><strong>const</strong></font> <font color="#2e8b57"><strong>char</strong></font>* name, WFlags fl )
<font color="#804040">11</font> : CHelloWorldWindow( parent, name, fl )
<font color="#804040">12</font> {
<font color="#804040">13</font> <font color="#0000ff">// no need to implement some extra stuff here</font>
<font color="#804040">14</font> <font color="#0000ff">// if PushButton1 is clicked, then showGreeting</font>
<font color="#804040">15</font> QObject::connect(
<font color="#804040">16</font> <font color="#804040"><strong>reinterpret_cast</strong></font><QObject*>(PushButton1),
<font color="#804040">17</font> SIGNAL( clicked() ),
<font color="#804040">18</font> <font color="#804040"><strong>this</strong></font>,
<font color="#804040">19</font> SLOT( showGreeting() )
<font color="#804040">20</font> );
<font color="#804040">21</font> }
<font color="#804040">22</font>
<font color="#804040">23</font> CHelloWorld::~CHelloWorld()
<font color="#804040">24</font> {
<font color="#804040">25</font> <font color="#0000ff">// no need to delete child widgets, Qt does it all for us</font>
<font color="#804040">26</font> }
<font color="#804040">27</font>
<font color="#804040">28</font> <font color="#0000ff">// Slot function; called if PushButton1 is sends clicked() Signal</font>
<font color="#804040">29</font> <font color="#2e8b57"><strong>void</strong></font> CHelloWorld::showGreeting()
<font color="#804040">30</font> {
<font color="#804040">31</font> QString message = <font color="#ff00ff">"Hallo "</font>+ LineEdit1->text() +<font color="#ff00ff">"!</font><font color="#6a5acd">\n</font><font color="#ff00ff">"</font>;
<font color="#804040">32</font>
<font color="#804040">33</font> <font color="#804040"><strong>if</strong></font> ( RadioButton1->isChecked() )
<font color="#804040">34</font> {
<font color="#804040">35</font> message += <font color="#ff00ff">"Das freut mich, dass es Ihnen gut geht!"</font>;
<font color="#804040">36</font> }
<font color="#804040">37</font> <font color="#804040"><strong>else</strong></font> <font color="#804040"><strong>if</strong></font> ( RadioButton2->isChecked() )
<font color="#804040">38</font> {
<font color="#804040">39</font> message += <font color="#ff00ff">"Tut mir leid, dass es Ihnen schlecht geht!"</font>;
<font color="#804040">40</font> }
<font color="#804040">41</font> <font color="#804040"><strong>else</strong></font>
<font color="#804040">42</font> {
<font color="#804040">43</font> message = <font color="#ff00ff">"Bitte einen der beiden Checkpunkte selektieren !"</font>;
<font color="#804040">44</font> }
<font color="#804040">45</font> QMessageBox::information(<font color="#804040"><strong>this</strong></font>, <font color="#ff00ff">"GrussFenster"</font>, message, QMessageBox::Ok);
<font color="#804040">46</font> }
|
| Listing 3: chelloworld.cpp |
Makefile
Was uns jetzt noch zum Kompilieren fehlt, ist ein passendes Makefile, das die ganzen Definitionen enthält, die benötigt werden, um unser Qt-Programm zu kompilieren und zu linken.
Das Programm TMake nimmt uns hierbei viel Arbeit ab und generiert automatisch das passende Makefile für GNU/Linux, Microsoft Windows oder UNIX, je nachdem, auf welchem System wir gerade arbeiten. Das einzige, was TMake benötigt, ist eine Konfigurationsdatei, die wesentliche Angaben enthält, die von TMake entsprechend in ein Makefile umgearbeitet werden. Nachfolgend eine passende Konfigurationsdatei *.pro für das obige Programmbeispiel. Durch die enthaltenen Kommentare sollte der Aufbau selbsterklärend sein.
<font color="#804040"> 1</font> <font color="#0000ff">#.................................. Defaults fuer eine Qt-Applikation</font> <font color="#804040"> 2</font> TEMPLATE = app <font color="#804040"> 3</font> CONFIG += qt warn_on release <font color="#804040"> 4</font> DEPENDPATH = <font color="#804040"> 5</font> REQUIRES = full-config <font color="#804040"> 6</font> <font color="#804040"> 7</font> <font color="#0000ff">#.................................. Projekt-spezifische Einstellungen</font> <font color="#804040"> 8</font> <font color="#0000ff"># fuer die *.ui Dateien des QtDesigner</font> <font color="#804040"> 9</font> INTERFACES = CHelloWorldWindow.ui <font color="#804040">10</font> <font color="#804040">11</font> <font color="#0000ff">#.............................. alle (eigene) *.h Dateien des Projekt</font> <font color="#804040">12</font> <font color="#0000ff"># vom QtDesigner generierte HEADER</font> <font color="#804040">13</font> <font color="#0000ff"># muessen nicht deklariert werden,</font> <font color="#804040">14</font> <font color="#0000ff"># wenn die *.ui Datei bereits bei</font> <font color="#804040">15</font> <font color="#0000ff"># INTERFACES angegeben wurde</font> <font color="#804040">16</font> HEADERS = chelloworld.h <font color="#804040">17</font> <font color="#804040">18</font> <font color="#0000ff">#............................ alle (eigene) *.cpp Dateien des Projekt</font> <font color="#804040">19</font> <font color="#0000ff"># vom QtDesigner generierte SOURCE</font> <font color="#804040">20</font> <font color="#0000ff"># muessen nicht deklariert werden,</font> <font color="#804040">21</font> <font color="#0000ff"># wenn die *.ui Datei bereits bei</font> <font color="#804040">22</font> <font color="#0000ff"># INTERFACES angegeben wurde</font> <font color="#804040">23</font> SOURCES = main.cpp \ <font color="#804040">24</font> chelloworld.cpp <font color="#804040">25</font> <font color="#804040">26</font> <font color="#0000ff">#................................................. DEFINE Anweisungen</font> <font color="#804040">27</font> DEFINES = <font color="#804040">28</font> <font color="#804040">29</font> <font color="#0000ff">#.............................. wie soll die Binary spaeter heissen ?</font> <font color="#804040">30</font> TARGET = HelloWorld <font color="#804040">31</font> <font color="#804040">32</font> <font color="#0000ff">#........................ bestimmte Konfigurationen fuer Linux / Unix</font> <font color="#804040">33</font> unix:LIBS = <font color="#804040">34</font> unix:INCLUDEPATH = $(QTDIR)/include <font color="#804040">35</font> unix:TMAKE_UIC = $(QTDIR)/bin/uic <font color="#804040">36</font> <font color="#804040">37</font> <font color="#0000ff">#............................. bestimmte Konfigurationen fuer Windows</font> <font color="#804040">38</font> win32:INCLUDEPATH = $(QTDIR)/include <font color="#804040">39</font> win32:LIBS = $(QTDIR)/lib/qt-mt230nc.lib \ <font color="#804040">40</font> $(QTDIR)/lib/qtmain.lib <font color="#804040">41</font> win32:TMAKE_CFLAGS = -MD -DQT_DLL -DQT_THREAD_SUPPORT -DNO_DEBUG <font color="#804040">42</font> win32:TMAKE_CXXFLAGS = -MD -DQT_DLL -DQT_THREAD_SUPPORT -DNO_DEBUG <font color="#804040">43</font> win32:TMAKE_UIC = $(QTDIR)\bin\uic.exe |
| Listing 4: HelloWorld.pro (tmake Konfigurationsdatei) |
Ein Aufruf von tmake -o Makefile HelloWorld.pro erstellt aus der Datei HelloWorld.pro ein passendes Makefile. Dieses Makefile kann dann mit make (GNU/Linux bzw. UNIX) oder (Windows mit Visual C++) aufgerufen werden.

