[gelöst] Problem mit Signal und Slot

Alles rund um die Programmierung mit Qt
gehho
Beiträge: 10
Registriert: 24. Mai 2006 23:53

[gelöst] Problem mit Signal und Slot

Beitrag von gehho »

Hallo,

erstmal folgendes: ich bin völlig neu in QT und habe auch erst relativ wenig Erfahrung in C++, aber ich geb momentan mein bestes, das zu ändern. :) Ich habe mich auch schon durch diverse Threads hier gehangelt, habe die entsprechenden Stellen in der Doku gelesen usw, aber keine Lösung gefunden...

also ich habe folgendes Problem mit signals und slots:
ich möchte gerne, dass bei Klick auf meinen reset-Button mein QLCDNumber-Display auf 0 gesetzt wird. Außerdem soll bei Klick auf den Beenden-Button das Programm geschlossen werden. Dazu hab ich folgendes im Konstruktor meiner Klasse "Eingabe" stehen:

Code: Alles auswählen

	QPushButton *reset = newQPushButton( "Reset", this, "reset" );
	QPushButton *beenden = new QPushButton( "Beenden", this, "beenden" );

	connect( reset, SIGNAL(clicked()), this, SLOT(resetDisplay()) );
	connect( beenden, SIGNAL(clicked()), qApp, SLOT(quit()) );
Außerdem habe ich den Slot folgendermaßen implementiert (in der h-Datei als private slot deklariert):

Code: Alles auswählen

void Eingabe::resetDisplay() {
	lcd->display(0);
}
Der Beenden-Button funktioniert einwandfrei. Der Reset-Button allerdings nicht. Beim Starten bekomme ich die Meldung "QObject::connect: No such slot QWidget::resetDisplay()"
Meine Eingabeklasse erbt von QWidget, allerdings sollte "this" doch eigentlich auf mein Eingabe-Objekt zeigen und nicht auf QWidget, oder verstehe ich da was falsch? Der Konstruktor sieht folgendermaßen aus:

Code: Alles auswählen

Eingabe::Eingabe( QWidget *parent, const char *name ) : QWidget( parent, name )
Wäre super, wenn mir da vielleicht jemand weiterhelfen könnte!

Gruß,
gehho.
Zuletzt geändert von gehho am 29. Mai 2006 16:43, insgesamt 1-mal geändert.
patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Beitrag von patrik08 »

Wenn du subversion kennst: (machst du..)

svn co http://ciz.ch/svnciz/xls2sql/tmp0/ test
cd test
qmake
make


falls nicht....
http://en.wikipedia.org/wiki/Subversion_%28software%29
es lohnt sich es zu kennen um keine arbeitschrietten zu verlieren...

und kannst es vergleichen .... das macht genau wass du willst....aus einen alten beispiel... von diesem forum....
gehho
Beiträge: 10
Registriert: 24. Mai 2006 23:53

Beitrag von gehho »

erstmal danke für deine schnelle antwort!

aber so ganz blicke ich da nicht durch. ist das denn die einzige möglichkeit, so etwas zu realisieren? man kann also nicht mit "this" auf die Funktionen der Klasse zugreifen, wenn diese von einer anderen Klasse erbt??? Das würde mich sehr überraschen. Oder liegt das Problem woanders? Wie gesagt, ich habe kaum Ahnung von C++ und steige dementsprechend auch schnell bei deinem Beispiel aus...
QtBerserker
Beiträge: 71
Registriert: 15. Mai 2006 09:07

Beitrag von QtBerserker »

gehho hat geschrieben:erstmal danke für deine schnelle antwort!

aber so ganz blicke ich da nicht durch. ist das denn die einzige möglichkeit, so etwas zu realisieren? man kann also nicht mit "this" auf die Funktionen der Klasse zugreifen, wenn diese von einer anderen Klasse erbt??? Das würde mich sehr überraschen. Oder liegt das Problem woanders? Wie gesagt, ich habe kaum Ahnung von C++ und steige dementsprechend auch schnell bei deinem Beispiel aus...
Der this Zeiger ist der Zeiger auf das aktuelle Object (nicht Klasse :wink:), d.h. man kann auch this->myMember() schreiben oder das Object übergeben OtherObjectOrFunction->clone(this) zB. Folglich greift der this Zeiger in der geerbten Klasse auch immer auf das geerbtes Object/Klasse zu und nicht auf die Base Klasse.

patrik08, wozu das self() (war das Smalltalk?) zumahl Du es nicht benutzt?
patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Beitrag von patrik08 »

QtBerserker hat geschrieben: patrik08, wozu das self() (war das Smalltalk?) zumahl Du es nicht benutzt?

Code: Alles auswählen

//main.cpp
#include "nummer_increment.h" 
#include <QApplication>

int main(int argc, char *argv[]) {
    
    QApplication a( argc, argv );
	Nummer_Increment::self()->show();
    a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) );
    return a.exec();
};
Mit dem self QPointer kann mann ueberall zugreifen... auf andere classen ohne emit ... wenn mal viele file da sind und ausserdem ist dieses file eine template die in 1 sekunden geschrieben worden mit ajax http://ppk.ciz.ch/qt_c++/qt/res.html genau wie es dass qt studio macht ...
http://qt4ds-monkey.sourceforge.net/ . &&& wenn mal das ui file da ist vom designer... ist die applikation in weniger als 10 sekunden fertig....

Geht selber auf und wieder zu.... durch den void closeEvent( QCloseEvent* ); diesem destruktor funktioniert einfach immer....

Code: Alles auswählen

#ifndef NUMMER_INCREMENT_H
#define NUMMER_INCREMENT_H
//
#include "ui_nummer_increment.h"
//
/*  Save file as nummer_increment.h  */
/*  Class Nummer_Increment Created on Sun May 14 13:27:30 CEST 2006  */
//
#include <QPointer>
//
class Nummer_Increment : public QDialog, public Ui::Nummer_Increment
{
	Q_OBJECT
	//
public:
	static Nummer_Increment* self( QWidget* = 0 );
	//
protected:
	void closeEvent( QCloseEvent* );
	//
private:
	Nummer_Increment( QWidget* = 0 );
	static QPointer<Nummer_Increment> _self;
	//
  public slots:
void setnull();

};
//
#endif // NUMMER_INCREMENT_H
und um dialoge zu oeffnen ... geht es relativ ohne viel schreibarbeit....

Code: Alles auswählen

/* open dialogs */
void Gui_Main::LanguageList()
{
  Gui_Languagelist::self( this )->exec(); 
}
patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Beitrag von patrik08 »

der self kann entscheiden wenn einen erbobjekt kommt oder nicht..

ob in sich selber aufmachen oder ein neuen dialog ....

Nummer_Increment* Nummer_Increment::self( QWidget* parent )

Code: Alles auswählen

#include "nummer_increment.h"
//
/*  Save file as nummer_increment.cpp  */
/*  Class Nummer_Increment Created on Sun May 14 13:27:30 CEST 2006  */
//
#include <QCloseEvent>
//
QPointer<Nummer_Increment> Nummer_Increment::_self = 0L;
//
Nummer_Increment* Nummer_Increment::self( QWidget* parent )
{
	if ( !_self )
		_self = new Nummer_Increment( parent );
	return _self;
}
//
Nummer_Increment::Nummer_Increment( QWidget* parent )
	: QDialog( parent )
{
	setupUi( this );
    
    connect(tonullaction, SIGNAL(clicked()), this , SLOT(setnull()));
}
//


void Nummer_Increment::setnull()
{
	 lcdNumber->display(0); 
         horizontalSlider->setValue(0);
}
gehho
Beiträge: 10
Registriert: 24. Mai 2006 23:53

Beitrag von gehho »

QtBerserker hat geschrieben:Der this Zeiger ist der Zeiger auf das aktuelle Object (nicht Klasse :wink:), d.h. man kann auch this->myMember() schreiben oder das Object übergeben OtherObjectOrFunction->clone(this) zB. Folglich greift der this Zeiger in der geerbten Klasse auch immer auf das geerbtes Object/Klasse zu und nicht auf die Base Klasse.
So hatte ich mir das auch gedacht. Aber wieso bekomme ich dann folgenden Fehler:

Code: Alles auswählen

QObject::connect: No such slot QWidget::resetDisplay()
Man beachte, dass er sagt, dass QWidget den Slot nicht hat. Der this-Zeiger sollte aber eigentlich auf mein von QWidget abgeleitetes Objekt vom Typ Eingabe zeigen, und dieses Objekt hat sehr wohl einen Slot resetDisplay(). Aber das scheint QT nicht zu finden. Woran kann das liegen?? Muss ich vielleicht den connect-Befehl ändern?
patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Beitrag von patrik08 »

>>>>Außerdem habe ich den Slot folgendermaßen implementiert (in der h-Datei als private slot deklariert): <<<<<<

Warum private...???

public slots:
void resetDisplay(); /* deklaration in der h datei */

muss funktionieren wenn im source cpp file die funktion da ist
gehho
Beiträge: 10
Registriert: 24. Mai 2006 23:53

Beitrag von gehho »

patrik08 hat geschrieben:Warum private...???

public slots:
void resetDisplay(); /* deklaration in der h datei */
sorry, mein fehler. hab es mittlerweile längst als public slot deklariert, aber es kommt immer noch der gleiche fehler.
patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Beitrag von patrik08 »

dann kann ich auch nicht weiter helfen.. da ich zu wenig source sehe.. um zu sagen wo andere fehler sind ... ob **.pro datei oder libs header deklarationen ecc... ich kenne C++ & qt4 seit 3 monaten .. am meistens habe ich von vorhandenen qt4 source programme (bei sf.net suche qt4) gelernt (+ grep von linux im source) und http://qt4ds-monkey.sourceforge.net/ sowie http://www.qtcentre.org/forum/ und nicht zuletzt dieses forum...
QtBerserker
Beiträge: 71
Registriert: 15. Mai 2006 09:07

Beitrag von QtBerserker »

eben gefunden, evtl. hilft Dir http://doc.trolltech.com/4.1/signalsandslots.html weiter zumindest bzgl. Signal&Slots in Qt. Für C++ lernen ist Qt imo weniger geeignet, es gibt aber gute Tutorials im Web. Immerhin scheint Qt4 die STL stärker zu unterstützen als in Qt3.

Olaf
gehho
Beiträge: 10
Registriert: 24. Mai 2006 23:53

Beitrag von gehho »

danke, die doku hab ich mir schon angesehen. hab ja auch eigentlich alles so gemacht, wie es da steht, aber er will das mit der geerbten klasse nicht so ganz verstehen... ich werd wohl weiter rumprobieren müssen.
uhu01
Beiträge: 150
Registriert: 10. Juli 2005 20:46

Beitrag von uhu01 »

Hy!

Hast du bei deiner Klassendefinition am Begin ein Q_OBJECT eingebaut?
Lässt du den MOC deine Klasse verarbeiten?

Das währen im Moment die ersten Dinge die mir einfallen.
Wird ein Slot nicht gefunden bringt Qt übrigens immer diesen Fehler, egal ob es sich um ein QObject handelt, oder um eine Ableitung davon.

mfg
uhu01
gehho
Beiträge: 10
Registriert: 24. Mai 2006 23:53

Beitrag von gehho »

uhu01 hat geschrieben:Hast du bei deiner Klassendefinition am Begin ein Q_OBJECT eingebaut?
ja, habe ich. der beenden-button funktioniert ja merkwürdigerweise auch. oder ist das eine ausnahme, weil das über qApp läuft?
uhu01 hat geschrieben:Lässt du den MOC deine Klasse verarbeiten?
wie kann ich das feststellen? benutze kdevelop und lasse das alles automatisch mit diesem integrierten qmake-manager (oder so ähnlich) erstellen. muss ich da evtl. noch manuell in der pro-datei oder im make-file rumbasteln?

danke für eure hilfe. bin im moment leider nicht zu hause. werde mich aber morgen nochmal mehr über den moc informieren.
uhu01
Beiträge: 150
Registriert: 10. Juli 2005 20:46

Beitrag von uhu01 »

Hy!

Wenn du zu Hause bist, poste mal deinen Quell Code, irgendwo muss der Fehler ja liegen.

mfg
uhu01
Antworten