[teilw. gelöst]Signal/Slot über mehrere Klassen

Alles rund um die Programmierung mit Qt
Antworten
The_EcKo
Beiträge: 9
Registriert: 20. November 2009 09:39

[teilw. gelöst]Signal/Slot über mehrere Klassen

Beitrag von The_EcKo »

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

Code: Alles auswählen

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

Code: Alles auswählen

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

Code: Alles auswählen

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

Code: Alles auswählen

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

Code: Alles auswählen

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 :)
Zuletzt geändert von The_EcKo am 24. November 2009 10:29, insgesamt 3-mal geändert.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Da Du KeyCreate.h nicht includierst weiss der Compiler nicht dass KeyCreate von QObject abgeleitet ist und kann demnach auch nicht casten.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
The_EcKo
Beiträge: 9
Registriert: 20. November 2009 09:39

Beitrag von The_EcKo »

Hallo Christian81,

Danke für die schnelle Antwort, das problem ist aber dass keycreate
newkeydialog.hh includiert hat weil keycreate auf ein Signal von diesem Dialog reagieren muss(Key erstellen).
Wenn ich jetzt keycreate.hh in newkeydialog icludiere bekomme ich folgenden Fehler

Code: Alles auswählen


ISO C++ forbids declaration of `KeyCreate' with no type	newkeydialog.hh

in der Zeile
KeyCreate *keycreate;
Das wollte ich ja umgehen indem ich in newkeydialog.hh ganz oben

Code: Alles auswählen

class KeyCreate
gemacht habe.
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

Verstehe jetzt eben nicht wieso der Fehler hier auftritt.
- "class KeyCreate; " iss nen wunderschoener Forward
- connect iss eine Methode, die internas an QOBject Instanzen aufruft, um die über die Signal Slot Methoden zu verbinden. Das Connect ruft also intern an den übergebenen Instanzen Methoden von QOBject auf. deshalb will es als Parameter QObject Zeiger haben !

du uebergibst aber Keyclass Zeiger. Das connect an der stelle sieht aber nur das "class KeyCreate; " Damit weiss es zwar, das es KeyCreate gibt, aber ned das das auch nen QOBject ist.

Der Forward in deinem Header iss schon schoen !!!
Aber das connect hat mehr anforderungen, deshalb braucht das connect die Deklaration von KeyCreate.
Das gute ist aber, der connect ist in der cpp, also braucht es nur intern die Deklaration. Was bedeutet, das du das #include "Keyclass.h" in deiner NewKeyDialog.cpp machen kannst. Was weitaus weniger Abhaengigkeiten von Keyclass erzeugt.
Die Folge, alle klassen die NewKeyDialog deklariert brauchen, brauchen keinerlei infos ueber Keyklass, nur das es die Klasse gibt (forward) wird ihnen mitvererbt, aufn ersten blick vielleicht unschoes, aufn 2. blick gar ned mal so schlecht, weil es unter umstanden vor doppelten Definitionen schuetzt. der Compiler meckert dann scho etwas eher, falls man irgendwo noch ein anderes global zugaengliches Keyclass definiert.

Also einfach das include in die cpp noch rein, und alles ist perferkt

war das einigermassen verstaendlich ?

noch was
.cc
.hh
wer verwendet solche Endungen ??? ^^

Edit: grad nachgeschaut, im gcc werden die .cc und .hh als c++ interpretiert. Also vergiss den Einwand, alles ok !
Kam mir nur etwas "ungewöhnlich" vor :-)


Ciao ....
Zuletzt geändert von RHBaum am 20. November 2009 12:34, insgesamt 1-mal geändert.
The_EcKo
Beiträge: 9
Registriert: 20. November 2009 09:39

Beitrag von The_EcKo »

@RHBaum

Ahhh jetzt geht es vielen vielen Dank =)

wegen cc und hh mein Vorgänger bei diesem Projekt hat das Ganze so eingerichtet von daher einfach weitergemacht^^
The_EcKo
Beiträge: 9
Registriert: 20. November 2009 09:39

Beitrag von The_EcKo »

Servus ich bins nochmal :D

Also kompilieren klappt jetzt wunderbar nur beim ausführen kommt es jetzt zu Problemen:
Und zwar stoppt das Programm jedesmal wenn es zum

Code: Alles auswählen

connect(keycreate, SIGNAL(maxKeys(QString)), this, SLOT(deleteFromNameList(QString)));
in newkeydialog.cc kommt

Der Debugger gibt mir folgende Meldung:

Code: Alles auswählen

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 qobect.cpp sieht so aus

Code: Alles auswählen

QMutexLocker locker(signalSlotLock(this));
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Beitrag von RHBaum »

QMutexLocker locker(signalSlotLock(this));
wenn der auf diese Zeile fliegt, dann ist deine connection aber queued ... das heisst dein signal wird in nem anderen Thread gefeuert, als wie der Slots es empfaengt, richtig ???

Ciao ...
The_EcKo
Beiträge: 9
Registriert: 20. November 2009 09:39

Beitrag von The_EcKo »

Hm soweit ich das überblicke werden aber im restlichen Programm keine Threads gestartet die das Signal beeinträchtigen könnten.
Oder hab ich dich falsch verstanden?
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Beitrag von AuE »

Ansonsten ist ein Mutex naja sagen wir sinnlos. Daher hatte er die Vermutung. Mutex is ja zum Schutz bei Multithreaded da.
The_EcKo
Beiträge: 9
Registriert: 20. November 2009 09:39

Beitrag von The_EcKo »

Hab mein Ursprungsproblem jetzt ohne Signale gelöst weil ich nicht mehr so die Zeit hatte mich damit zu beschäftigen :D
Aber trotzdem danke an alle die geholfen haben.
Antworten