undefined reference to `typeinfo for ...'
-
Ich nutze Plugins zur Darstellung verschiedener Modalitäten von Daten (Video, 3D, Sound, ...). Die Plugins sind als Factory realisiert und funktionieren im Program (dh. die Stellen die Daten korrekt dar, die Buttons funktionieren usw.). Jeder von dem Plugin instantiierter "Wrapper" gibt sein display() an ein QMdiSubWindow und seine buttons() an eine QTabBar weiter.
Ich versuche an einer neuen Stelle nun aus dem MDISubwindow das QWidget (==wrapperklasse) per dynamic_cast<KonkreterWrapper*>(QWidget*) auf den korrekten Wrapper zurück zu casten (auch per qobject_cast<.>(.) versucht). Bei beiden Cast erhalte ich Fehler (siehe Kommentar im Code)
// QMdiArea * mdiArea; // holds the QMdiSubWindows which have a PluginWrapper as QWidget foreach (QMdiSubWindow * oneSubWin, mdiArea->subWindowList()) { // get the widget from the subwindow QWidget * wid = oneSubWin->widget(); // cast it into fitting modality AnnotationWrap * an_wrap1 = 0, * an_wrap2 = 0; an_wrap1 = dynamic_cast<AnnotationWrap*>(wid); // undefined reference to 'typeinfo for AnnotationWrap' an_wrap2 = qobject_cast<AnnotationWrap*>(wid); // undefined reference to 'AnnotationWrap::staticMetaObject' if (an_wrap1) qDebug("dynamic_cast worked"); if (an_wrap2) qDebug("dqobject_cast worked"); }
Google informierte mich über den dynamic_cast - Fehler: das passiert wenn man virtual deklarierte Methoden in der Basisklasse mit ; abschließt statt ein leeren Rumpf ('{ }') dran zu hängen. Mein WrapperInterface hat aber nur pure virual Methoden. Das einzige nicht
pure virtual
deklarierte ist der destructor und der hat einen leeren Rumpf.Was mach ich falsch?
gekürzter Code für PluginInterface, ein Beispiel-Plugin und den exemplarischen Wrapper:
factoryinterface.h
#ifndef FACTORYINTERFACE_H #define FACTORYINTERFACE_H #include <QtCore/QString> #include <QtGui/QWidget> #include "data_classes/modalitybase.h" class FactoryInterface { public: virtual ~FactoryInterface() {} // unique id - no other plugin should have this id virtual QString id() const = 0; // file filter string i.e. "*.c3d *.txt *.csv" virtual QString fileFilter() const = 0; // factory method virtual QWidget * createPlugin(bool clicked, ModalityBase * mod) = 0; }; Q_DECLARE_INTERFACE(FactoryInterface, "padreigh.FactInterface/1.0"); #endif // FACTORYINTERFACE_H
Beispiel-Plugin:
annottxtplugin.h
// .h #ifndef ANNOTTEXTPLUGIN_H #define ANNOTTEXTPLUGIN_H #include <QtCore/QObject> #include "factoryinterface.h" #include "data_classes/modalitybase.h" #include <QtCore/QString> #include <QtCore/QPair> #include <QtCore/QMap> class AnnotationTxtPlugin : public QObject, FactoryInterface { Q_OBJECT Q_INTERFACES(FactoryInterface) public: static const QString magicID; inline QString id() const { return magicID; } inline QString fileFilter() const { return QString("*.annottxt"); } public slots: QWidget * createPlugin(bool,ModalityBase*); }; #endif // ANNOTTEXTPLUGIN_H
annottxtplugin.cpp
.cpp #include <QtGui> #include "annottxtplugin.h" #include "annotationwrap.h" #include "data_classes/modalities/modalityannotationtxt.h" const QString AnnotationTxtPlugin::magicID = "AnnotationTxtPlugin/1.0"; QWidget * AnnotationTxtPlugin::createPlugin(bool clicked, ModalityBase * mod) { if (clicked) { return new AnnotationWrap(static_cast<ModalityAnnotationTxt*>(mod),0); } return 0; } Q_EXPORT_PLUGIN2(annottxtplugin, AnnotationTxtPlugin);
WrapperWidget:
wrapperinterface.h
class QWidget; // each wrapper MUST implement the methods defined here-in. // - display() is a QWidget which will be displayed inside a QMdiSubWindow // - buttons() is a QWidget which will be displayed inside a QTabBar // - exportData() is called to export the visualized data // - setupDisplay() and setupButtons() MUST be called in the constructor to setup the corresponding widgets. class WrapperInterface { public: virtual ~WrapperInterface() {} virtual QWidget * display() const = 0; virtual QWidget * buttons() const = 0; protected: // methods virtual void setupDisplay() = 0; virtual void setupButtons() = 0; virtual void exportData() = 0; };
annotationwrap.h
#ifndef ANNOTATIONWRAP_H #define ANNOTATIONWRAP_H #include <QtCore/QTime> #include <QtGui/QWidget> #include "wrapperinterface.h" #include "data_classes/modalities/modalityannotationtxt.h" class QTableWidget; class AnnotationWrap : public QWidget, WrapperInterface { Q_OBJECT public: AnnotationWrap(ModalityAnnotationTxt *, QWidget * parent = 0); QWidget * buttons() const { return butt; } QWidget * display() const { return disp; } QSize minimumSize() const {return QSize(200,100);} public slots: void exportData(); // some more slots signals: // some signals private: QWidget * disp; // the display widget QWidget * butt; // the button widget // some more members void setupDisplay(); void setupButtons(); private slots: // some private slots }; #endif // ANNOTATIONWRAP_H
annotationwrap.cpp
#include "annotationwrap.h" #include <QtGui/QInputDialog> #include <QtGui/QLineEdit> #include <QtGui/QRegExpValidator> #include <QtGui/QHBoxLayout> #include <QtGui/QPushButton> #include <QtGui/QTableWidget> #include <QtGui/QTableWidgetItem> AnnotationWrap::AnnotationWrap(ModalityAnnotationTxt * mod, QWidget * parent) : QWidget(parent), m_mod(mod), table(0), disp(0), butt(0) { // parses the data from file on harddisc, // data is accessible through m_mod's methods m_mod->parseAll(); setupDisplay(); // setup disp; setupButtons(); // setup butt; QHBoxLayout * lay = new QHBoxLayout; lay->addWidget(disp); setLayout(lay); // some more QWidget() method calls } void AnnotationWrap::setupDisplay() { qDebug() << "AnnotationWrap::setupDisplay()"; disp = new QTableWidget(); // code that fills the TableWidget with the data gathered by calling m_mods's methods } void AnnotationWrap::setupButtons() { qDebug() << "AnnotationWrap::setupButtons()"; butt = new QWidget; // code that puts some buttons into 'butt' and connects them to slots that modify the data or visulisation } void AnnotationWrap::exportData() { qDebug() << "AnnotationWrap::exportData()"; }
-
nevermind... ich hab die benötigten Informationen als poperty an das QMdiSubWindow gehängt ...
-
Hi,
ich habe gerade einen ähnlichen Fehler. Wenn du dich noch an deine Lösung erinnern kannst (ist ja nu schon ne Weile her), würdest du mir diese in etwas detaillierter Form beschreiben. Ich weiß nicht, wie ich raus finde, welche Informationen in den Klassen fehlen.
-
Die Lösung findet sich natürlich immer sofort nachdem man in einem Forum dazu eine Frage gestellt hat.
Mein Fehler war doch ein völlig anderer, bei mir lag es daran, dass ich das Q_OBJECT-Makro inkludiert habe. Ich kann nicht sagen warum, aber durch auskommentieren der Zeile war mein Problem gelöst.