Linkerfehler 2001 mit Signals und Slots
-
Hallo liebe Leute,
ich habe ein Problem, welches ich nicht verstehe.
Zuerst einmal: Ich bin neu in der Qt-Programmierung.
Mein Problem: Ich wollte über einen simplen QPushButton Klick einen QFileDialog öffnen.
Hier mein Code:
Header-Datei
#include <qfiledialog.h> #define QFILEDIALOG_H //class ImportDialog : public QFileDialog { class ImportDialog : public QObject{ Q_OBJECT public: ImportDialog(); ~ImportDialog(); public slots: void load(QWidget* parent = 0); signals: void fileLoaded(); };
CPP-Datei
#include <qfiledialog.h> #include <qwidget.h> #include "import.h" //ImportDialog::ImportDialog(QWidget* parent, const char* name) : QFileDialog(parent,name) { ImportDialog::ImportDialog() { } ImportDialog::~ImportDialog() { } void ImportDialog::load(QWidget* parent) { QFileDialog* dia = new QFileDialog(parent, "file dialog"); dia->setDir("./"); dia->addFilter("Logs (*.txt)"); } void ImportDialog::fileLoaded() { }
Anwendung
QObject::connect(browse, SIGNAL(clicked()), new ImportDialog(), SLOT(load(main)));
browse ist hierbei der QPushButton und main ein QWidget.
Ich kriege folgende Fehlermeldungen, wenn ich diesen Code kompilieren möchte:
1>import.obj : error LNK2001: unresolved external symbol "public: virtual char const * __thiscall ImportDialog::className(void)const " (?className@ImportDialog@@UBEPBDXZ)1>import.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall ImportDialog::qt_cast(char const *)" (?qt_cast@ImportDialog@@UAEPAXPBD@Z)
1>import.obj : error LNK2001: unresolved external symbol "public: virtual bool __thiscall ImportDialog::qt_invoke(int,struct QUObject *)" (?qt_invoke@ImportDialog@@UAE_NHPAUQUObject@@@Z)
1>import.obj : error LNK2001: unresolved external symbol "public: virtual bool __thiscall ImportDialog::qt_emit(int,struct QUObject *)" (?qt_emit@ImportDialog@@UAE_NHPAUQUObject@@@Z)
1>import.obj : error LNK2001: unresolved external symbol "public: virtual bool __thiscall ImportDialog::qt_property(int,int,class QVariant *)" (?qt_property@ImportDialog@@UAE_NHHPAVQVariant@@@Z)
1>import.obj : error LNK2019: unresolved external symbol "public: static class QMetaObject * __cdecl ImportDialog::staticMetaObject(void)" (?staticMetaObject@ImportDialog@@SAPAVQMetaObject@@XZ) referenced in function "public: virtual class QMetaObject * __thiscall ImportDialog::metaObject(void)const " (?metaObject@ImportDialog@@UBEPAVQMetaObject@@XZ)
1>C:\BuildBaseForFrank\Release\HelloWorld.exe : fatal error LNK1120: 6 unresolved externals
Wenn ich in der CPP-Datei den Kon- und Destruktor auskommentiere gibt es keine Fehler.
Was ist an meinem Code falsch oder was habe ich vergessen? Ich wäre für Hilfe und Aufklärung, was das Problem angeht, sehr dankbar!
Gruß limbo
-
qmake neu ausgeführt?
-
limbo schrieb:
Wenn ich in der CPP-Datei den Kon- und Destruktor auskommentiere gibt es keine Fehler.
Das nehm ich dir nicht ab
Ich nehme an dass der Fehler verschwindet, sobald du das Q_OBJECT in der Klassedefinition auskommentierst.
Problem: Q_OBJECT deklariert einige virtuelle Funktionen. Werden die nicht implementiert gibts nen Linker-Error.
Lösung: Der moc übernimmt für dich das Implementieren. Einfach das .pro editieren und die ZeileHEADERS += importdialog.h
einfügen (oder wie bei dir der Header heißt).
evtl. nochmal qmake ausführen (sollte automatisch geschehen), in ganz harten Fällen wurde auch schonmal einmake clean
notwendig.
-
Vielen Dank erstmal für die Antworten.
Es stimmt, dass wenn ich Q_Object auskommentiere keine Linkerfehler mehr kommen. Allerdings liegt es nicht an dem HEADERS += xxx.h Eintrag.
Fehler ist wohl, dass bei mir keine moc-Dateien, welche die Implementierung der fehlenden Methoden beinhalten, erstellt werden.
Ich werde mich nochmal dransetzen und dann die Lösung posten.
Gruß limbo
-
limbo schrieb:
QObject::connect(browse, SIGNAL(clicked()), new ImportDialog(), SLOT(load(main)));
Lies nochmal ein paar Beispiele (oder das Kapitel) über SIGNALs/SLOTs. Du kannst beim Verbinden keine Parameter mitgeben. Du kannst allerhöchstens Parameter weglassen (zB. hypotetisch
connect(myclass,SIGNAL(tollesSignal(int,bool,QString)),myOtherClass,SLOT(tollerSlot(int));
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0); ~MainWindow(); public slots: void pressMe_pressed(); private: QString * name; }; #endif // MAINWINDOW_H
#include "mainwindow.h" #include <QtGui> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { name = new QString; QWidget * center = new QWidget; { QHBoxLayout * hlayout = new QHBoxLayout; { QPushButton * pbut = new QPushButton(QString("PressMe")); connect(pbut,SIGNAL(clicked()),this,SLOT(pressMe_pressed())); hlayout->addWidget(pbut); } center->setLayout(hlayout); } setCentralWidget(center); } MainWindow::~MainWindow() { delete name; } void MainWindow::pressMe_pressed() { name->clear(); name->append(QFileDialog::getOpenFileName( this, tr("DialogTitel"), QDir::homePath(), tr("Logs (*.txt)"))); QMessageBox::information(this->centralWidget(),tr("FileChoosen:"),name->toAscii(),QMessageBox::Ok); }
edit:: ui namespace noch rausgenommen
-
Es lag wirklich am qmake. Allerdings war ein clean notwendig.
Vielen Dank nochmal für die Tipps.
Gruß limbo