[QT]Signal/Slot Problem über mehrere Klassen
-
Hallo zusammen,
Ich schreibe gerade ein aufwendigeres Programm mit Oberfläche.
Es geht nun darum, dass eine Auswahl aus einer QComboBox gelöscht werden soll. Die entsprechende Funktion dazu soll aufgerufen werden sobald eine Klasse ein bestimmtes Signal sendet.Zuerst einmal wo das Signal herkommt
keycreate.hh class KeyCreate : public QWidget { Q_OBJECT //nicht relevanter Code signals: void maxKeys(const QString &name); //dieses Signal wird naher gesendet private slots: void createNewItemKey(const QString& name = ""); //Das Signal kommt von dieser Funktion
Nun die egentliche Funktion mit dem sendes des Signals
keycreate.cc void KeyCreate::createNewItemKey(const QString& name) { QString tmpName; //nicht relevanter Code if((keyTable->findItems(tmpName, Qt::MatchExactly)).size()!=0 && KeyTable->findItems(tmpName, Qt::MatchExactly).size()!=0) { emit maxKeys(tmpName); //hier wird also das Signal gesendet //mit einer Variablen zusammen }
Jetzt die Klasse, die auf das Signal reagieren soll
newkeydialog.hh #ifndef NEWKEYDIALOG_HH #define NEWKEYDIALOG_HH #include <QDialog> #include <QLabel> #include <QPushButton> #include <QComboBox> class KeyCreate; class NewKeyDialog : public QDialog { Q_OBJECT //nicht relevanter Code private slots: void deleteFromNameList(const QString &name); //Diese Function soll ausgeführt werden wenn das Signal kommt private: KeyCreate *keycreate;
Jetzt Aufruf des connects und die Funktion
newkeydialog.cc NewKeyDialog::NewKeyDialog(QWidget *parent) : QDialog(parent) { qDebug() << "Programmstatus: In NewKeyDialog::NewKeyDialog"; this->setMaximumSize(240, 205); this->setMinimumSize(240, 205); this->setWindowTitle(tr("Add Key")); this->setModal(true); modes << tr("Pressed") << tr("Released"); createNameList(); createLabels(); createButtons(); createComboBoxes(); connect(okButton, SIGNAL(clicked()), this, SLOT(accept())); connect(abortButton, SIGNAL(clicked()), this, SLOT(reject())); connect(keycreate, SIGNAL(maxKeys(QString)), this, SLOT(deleteFromNameList(QString))); //Dies ist der betreffende connect Aufruf } void NewKeyDialog::deleteFromNameList(const QString &name) { qDebug() << "Programmstatus: In NewKeyDialog::deleteFromNameList"; for(uint8_t i=0; i<nameList.size(); i++) { if(nameList[i]==name) //name found --> delete from list { nameList.removeAt(i); // nameList.sort(); comboName->clear(); comboName->addItems(nameList); return; } } }
Beim Kompilieren erscheint nun folgender Fehler in der newkeydialog.cc beim letzten connect Aufruf der quasi das Signal aus der anderen Klasse mit der Funktion verbinden soll
no matching function for call to `NewKeyDialog::connect(KeyCreate*&, const char[18], NewKeyDialog* const, const char[29])' newkeydialog.cc /line 23 C/C++ Problem
Verstehe jetzt eben nicht wieso der Fehler hier auftritt.
Bin für jede Hilfe dankbar, falls noch Code oder Erklärungen fehlen einfach meckern
-
Ok, ich bin mir nicht sicher und kanns grad leider nicht nachprüfen, aber du deklarierst den Übergabeparameter sowohl beim Signal als auch beim Slot mit einer konstanten Referenz auf ein QStirng-Objekt, versuchst aber den Connect nur über den Parameter QString.
Versuch mal die Zeile so zu ändern und versuch dann mal zu kompilieren:
connect(keycreate, SIGNAL(maxKeys(const QString&)), this, SLOT(deleteFromNameList(const QString&)));
Gruß
Wulfgar
-
Hallo wulfgar,
Das war auch meine erste Überlegung gewesen allerdings kommt dann beim kompilieren folgender Fehler
no matching function for call to `NewKeyDialog::connect(KeyCreate*&, const char[25], NewKeyDialog* const, const char[36])'
-
The_EcKo schrieb:
Hallo wulfgar,
Das war auch meine erste Überlegung gewesen allerdings kommt dann beim kompilieren folgender Fehler
no matching function for call to `NewKeyDialog::connect(KeyCreate*&, const char[25], NewKeyDialog* const, const char[36])'
Ok, jetzt ist mir was bei der Fehlermeldung aufgefallen. Und zwar das "KeyCreate*&" sieht so aus als würde er dein keycreate als eine Referenz auf einen Pointer ansehen. Warum auch immer. Hast du vielleicht im Header irgendwas am Typ von keycreate geändert oder ist das immernoch KeyCreate*?
-
Nein habe nichts geändert
ist immernochKeyCreate *keycreate;
in newkeydialog.hh
-
Wie initialisierst du keycreate?
Ne, vergiss es, das ist Unsinn. Von Initialisierungen zur Laufzeit hat der Kompiler eh keine Ahnung. Ich fürchte im Moment kann ich dir nicht helfen. Hab grad keinen Rechner mit QT in der Nähe auf dem ich das mal testen könnte. Vielleicht kann dir ja ein anderer helfen, bis ich dazu komm.
-
Ok, eine Idee hab ich noch: Du deklarierst KeyCreate in der Header von NewKeyDialog vor, aber includierst du dann den Header von Keycreate in der Code-Datei von NewKeyDialog?
Das ist was das ich sehr gerne vergesse und das gibt dann die merkwürdigsten Kompiler-Fehler.
-
Glaube der Fehler könnte daran liegen, dass ich
in newkeydialog.hh lediglich eine Forwarddeklaration gemacht habe mitclass KeyCreate;
deswegen kann er auch die Funktion nicht finden die er aufrufen soll.
Das nächste Problem dabei ist allerdings, newkeydialog.hh ist bereits in keycreate.hh includiert weil keycreate ein Signal von newkeydialog bekommt(Key erstellen)
Wenn ich jetzt aber keycreate.hh in newkeydialog.hh includiere kommt mir
ISO C++ forbids declaration of `KeyCreate' with no type newkeydialog.hh
in
newkeydialog.hh Keycreate *keycreate;
Haben wir wohl gerade denselben gedanken gehabt ^^
-
The_EcKo schrieb:
Glaube der Fehler könnte daran liegen, dass ich
in newkeydialog.hh lediglich eine Forwarddeklaration gemacht habe mitclass KeyCreate;
deswegen kann er auch die Funktion nicht finden die er aufrufen soll.
Das nächste Problem dabei ist allerdings, newkeydialog.hh ist bereits in keycreate.hh includiert weil keycreate ein Signal von newkeydialog bekommt(Key erstellen)
Wenn ich jetzt aber keycreate.hh in newkeydialog.hh includiere kommt mir
ISO C++ forbids declaration of `KeyCreate' with no type newkeydialog.hh
in
newkeydialog.hh Keycreate *keycreate;
Haben wir wohl gerade denselben gedanken gehabt ^^
Ja, das kommt daher, dass es C++ nicht mag, wenn sich Header gegenseitig verlinken. Dann musst du in der Header die Vorwärst-Deklaration machen und das include in der cpp machen, dann geht es.
Aber bist du sicher, dass du NewKeyDialog in KeyCreate includieren musst? Das Signal/Slot-Konstrukt kommt von QT kommt doch normalerweise ohne sowas aus.
-
Super wulfgar jetzt geht es sehr geil danke
Ja muss newkeydialog in keycreate bekommen weil das Signal accepted von newkeydialog wenn man auf "OK" drückt um einen Key zu erstellen an keycreate geht welches darauf hin die Funktion aufruft diesen Key tatsächlich zu erstellen.
-
Bitte schön. Freut mich doch, wenn ich helfen kann.
-
Servus ich bins nochmal
Also kompilieren klappt jetzt wunderbar nur beim ausführen kommt es jetzt zu Problemen:
Und zwar stoppt das Programm jedesmal wenn es zumconnect(keycreate, SIGNAL(maxKeys(QString)), this, SLOT(deleteFromNameList(QString)));
in newkeydialog.cc kommt
Der Debugger gibt mir folgende Meldung:
Program received SIGSEGV, Segmentation fault. 0x6a25bc00 in QObject::connect(QObject const*, char const*, QObject const*, char const*, QT::ConnectionType) (sender=0xbaadf00d, signal=0x5a5257 "2maxKeys(QString)", receiver=0x72574e8, method=0x5a523a "1deleteFromNameList(QString)", type=AutoConnection) at kernel/qobject.cpp:2463 2463 kernel/qobject.cpp : No such file or directory in kernel/qobject.cpp
Denke es liegt daran, dass dieser connect Aufruf im Konstruktor erfolgt und auch noch irgendwie mit der Forwarddeklaration zusammenhängt. Kann das Puzzle aber nicht ganz zusammensetzen
edit: DIe betreffende Zeile in qobject.cpp sieht so aus
QMutexLocker locker(signalSlotLock(this));