Ich staunte nicht schlecht darüber, als ich teils von Hand, teils vom QtCreator erzeugte GUI-Klassen nicht in Netbeans compilieren ließen.
Im Grunde bin ich mal wieder dabei ein sinnvolles und nutzbares Programm für den Hausgebrauch zu schreiben. Und das sollte nach Möglichkeit auch eine GUI haben. Obendrein war die Arbeit mit Qt auch mal angedacht gewesen.
Nun aber zu meinem eigentlichen Problem. Wenn ich zum Beispiel folgende Quelltexte versuchte zu compilieren, bekam ich stets diesen Fehler in Netbeans:
In function `TonerMainWindow':
/home/compiler/Netbeans-workspace/TonerV/TonerMainWindow.cpp:28: undefined reference to `vtable for TonerMainWindow'
Da wollte er weder den Konstruktor noch den Destruktor annehmen.
Der Code dazu:
tonermainwindow.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #ifndef _TONERMAINWINDOW_H #define _TONERMAINWINDOW_H #include // ein Haufen Qt-Includes class TonerMainWindow : public QMainWindow { Q_OBJECT public: QAction *actionBestand_anzeigen; QAction *actionToner_aus_geben; QAction *action_Beenden; QAction *action_ber_das_Programm; QWidget *centralwidget; QTableWidget *tableWidget; QPushButton *neuerTonerBtn; QPushButton *mengeAddBtn; QMenuBar *menubar; QMenu *menuAktionen; QMenu *menuInfo; QStatusBar *statusbar; TonerMainWindow(); virtual ~TonerMainWindow(){ }; void setupGUI(QMainWindow *TVMainWindow); void retranslateGUI(QMainWindow *TVMainWindow); protected: //void changeEvent(QEvent *e); private: private slots: }; #endif /* _TONERMAINWINDOW_H */ |
tonermainwindow.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include "TonerMainWindow.h" TonerMainWindow::TonerMainWindow() { setupGUI(this); } void TonerMainWindow::setupGUI(QMainWindow *TVMainWindow) { ... ganz viel Code ... } void TonerMainWindow::retranslateGUI(QMainWindow *TVMainWindow) { ... ganz viel Code ... } |
Ich habe anschließend gegoogelt, weil ich mit vtable so gar nichts anfangen konnte. Irgendwo habe ich dann auch gelesen, dass der vtable-Fehler eigentlich immer dann auftritt, wenn eine mit dem Schlüsselwort virtual markierte Funktion nicht definiert ist. Die einzige virtuelle Funktion wäre hier der Destruktor, der aber aus Gründen der Mehrfachvererbung in C++ immer als virtuelle Funktion definiert werden sollte.
Ahnungslos, was da eigentlich der Grund für diesen Fehler sein könnte, habe ich dann eine private Try-and-Error-Session eingelegt. Ich habe es mit Weglassen und später auch mit dem Makefile probiert. (Die Makefile-Episode lässt sich übrigens gleich hier nachlesen.)
Eine Googlesuche gab auch nicht viel her. Irgendwann hatte ich dann mal den Code so verändert, dass TonerMainWindow keine abgeleitete Klasse von QMainWindow ist, sondern eine Membervariable vom Typ QMainWindow besaß. Anschließend habe ich den Aufruf von setupGUI im Konstruktor so verändert, das da nicht mehr this sondern der Name der Membervariable da stand. Nach erfolgreichem Übersetzungsvorgang und Start des Programms, bekam ich endlich ein Fenster zu sehen.
Aber das war nicht die endgültige Lösung. Irgendwie konnte ich mich nicht ganz mit dem Gedanken abfinden, keine abgeleiteten Klassen zu verwenden. In Java mache ich das schließlich bei Swing-GUIs genauso. Aus Neugier habe ich dann Q_Object auskommentiert und es lief!
Q_Object ist ein Makro, aber was das treibt und für was das eigentlich gut sein soll, weiß ich nicht. Aber Hauptsache, es läuft.






Kommentare