PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Newbie-Problem: slot funzt nicht



df4ian
24-08-2006, 23:29
Moin Kinners,
ich lerne gerade den Umgang mit QT und habe das Schieberegler-Tutorial
umzustricken versucht. Der Schieberegler gibt ein int aus und das LC-Display zeigt dieses int dann an.
Soweit das Tutorial.

Ich habe nun versucht den int-Wert des Sliders (Schieberegler) mittels zusätzlicher Elementfunktion/Slot von einem int auf ein double abzuändern.
Das Anzeigen des Wertes funktioniert. Allerdings passiert beim Aufrufen der SlotFunktion welche das int in ein double wandeln soll überhaupt gar nix.

Wo liegt der Denkfehler?




/************************************************** **************
**
** Qt tutorial 5
**
************************************************** **************/

#include <qapplication.h>
#include <qpushbutton.h>
#include <qslider.h>
#include <qlcdnumber.h>
#include <qfont.h>

#include <qvbox.h>



class Test : public QLCDNumber //Meine erste erfolgreiche Vererbung. Whoaw !
{
int i;
double d;

public:
Test (int, QWidget *parent=0, const char *name=0 );
double GibAus (void);

public slots:
void GibEin (int);
};



Test::Test (int , QWidget *parent, const char *name )
: QLCDNumber( parent, name )
{
i=5;
}

double Test::GibAus (void) {
//d=7.1;
return d;
}

void Test::GibEin (int j) { // hier soll das int des Sliders reinkommen
d = j;
d*=0.5;

}




class MyWidget : public QVBox
{
public:
MyWidget( QWidget *parent=0, const char *name=0 );
};


MyWidget::MyWidget( QWidget *parent, const char *name )
: QVBox( parent, name )
{
QPushButton *quit = new QPushButton( "Quit", this, "quit" );
quit->setFont( QFont( "Times", 18, QFont::Bold ) );

connect( quit, SIGNAL(clicked()), qApp, SLOT(quit()) );

// QLCDNumber *lcd = new QLCDNumber( 2, this, "lcd" );
Test *lcd1 = new Test( 4, this, "lcd1" );

QSlider * slider = new QSlider( Horizontal, this, "slider" );
slider->setRange( 0, 99 );
slider->setValue( 3 );

// connect( slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)) ); // funzt
connect( slider, SIGNAL(valueChanged(int)), lcd1, SLOT (GibEin(int)) ); // macht keinen Mucks
lcd1->display( lcd1->GibAus() );
}


int main( int argc, char **argv )
{
QApplication a( argc, argv );

MyWidget w;
a.setMainWidget( &w );
w.show();
return a.exec();
}




Joachim

anda_skoa
24-08-2006, 23:51
Es fehlt das Q_OBJECT Macro bei Test



class Test : public QLCDNumber //Meine erste erfolgreiche Vererbung. Whoaw !
{
Q_OBJECT
int i;
double d;

public:
Test (int, QWidget *parent=0, const char *name=0 );
double GibAus (void);

public slots:
void GibEin (int);
};


Wenn man neue Slot oder Signals deklariert, oder die neue Klasse im Qt Typensystem erkennbar haben will, braucht man das Q_OBJECT Macro

Kleiner Tipp: wenn man nachträglich ein Q_OBJECT Macro einbaut, muß man das Makefile neu erstellen, damit die MOC Regeln für die Klasse eingefügt werden.

Ciao,
_

P.S: Codetags machen das Lesen von Code Stücken leichter, im Forumseditor das #-Zeichen

df4ian
25-08-2006, 13:39
Hi,
danke für die Antwort.


Leider bin ich nicht weitergekommen, im Gegenteil:
Nach fünf Stunden rumgedoktere bekomme ich nun

unresolved reference 'vtable' in class Test

Was bin ich genervt...

Das scheint wohl irgendwie mit den Linkereinstellungen zu tun zu haben...

locus vivendi
25-08-2006, 14:46
Das scheint wohl irgendwie mit den Linkereinstellungen zu tun zu haben...
Hast du dieses hier
Kleiner Tipp: wenn man nachträglich ein Q_OBJECT Macro einbaut, muß man das Makefile neu erstellen, damit die MOC Regeln für die Klasse eingefügt werden. berücksichtigt?

df4ian
25-08-2006, 15:53
Hmmmm,
um ehrlich zu sein, ich habe bis jetzt immer nur auf das Zahnrad-Icon geklickt und der Compiler/Linker hat losgerattert... mit den moc-files hab ich diese und jenes quergelesen, es aber nicht für wichtig gehalten. Scließlich wollte ich meine Anwendung und nicht make zum Laufen bringen ;-)

Ich werd' mal schauen ob ich's das irgendwie hinkriege.



Joachim

anda_skoa
25-08-2006, 17:19
Das gibt es eine Buildvariante, die auch die Buildsystem Dateien neu erstellt.

"neu erstellen" oder so ähnlich

Bei einem qmake ".pro" basiertem Build ist das praktisch ein neuer qmake Aufruf, bei einem autotools basiertem Projekt ein configure Aufruf.

Ciao,
_

df4ian
25-08-2006, 17:56
Hi,
Ich verwende kdevelop mit QT3. In einem älteren Post hatte jemand (brumm) ein sehr ähnliches Problem. Durch Auslagern der Klassendeklaration in ein *.h-file ließ sich das Problem elegant lösen.
Ist aber trotzdem seltsam.
Egal. Weiter.

Nun bin ich fast am Ziel...
Q_OBJECT steht in der Klasse und die Elementfunktion GibEin() läßt sich mit z.B. mit


lcd1->GibEin(55);
im Code manuell ansprechen.

Erstaunlicherweise bewirkt


connect( slider, SIGNAL(valueChanged(int)), lcd1, SLOT (GibEin(int)) ); // macht keinen Mucks

immer noch nix (als ob der Slot nicht verbunden wäre). Eine Fehlermeldung bekomme ich aber leider nicht. Könnte es sein, daß 'lcd1' für connect() quasi unsichtbar ist? Falsche Instanzierung von 'lcd1' ...? Hab noch nicht sooo viel Ahnung von Zehplusplus.


Joachim

df4ian
26-08-2006, 09:38
Hurra, gelöst!

Tja, Unwissenheit und Unerfahrenheit gesellen sich gerne...

C++ zwingt zu ganz neuem Denken, man muß von der klassischen (prozeduralen) Vorgehensweise von C Abstand nehmen ;-)


Jedenfalls:


connect( slider, SIGNAL(valueChanged(int)), lcd1, SLOT (GibEin(int)) ); // macht keinen Mucks
lcd1->display( lcd1->GibAus() );

...so funktioniert das nicht.


Während jedoch:


connect( slider, SIGNAL(valueChanged(int)), lcd1, SLOT (GibEin(int)) );


plus



void Test::GibEin (int j) { // hier soll das int des Sliders reinkommen
d = j;
d*=0.1;
display(d); // <- hier muß die Ausgabe stehen!
}


Zuerst hatte ich mit dem instanzierten Objekt lcd1 ziemliche Schwierigkeiten hinsichtlich des Gültigkeitsbereichs, es es war z.T. nicht sichtbar. Daraufhin habe ich es einfach weggelassen... und die Ausgabefunktion display() in die Methode der zu instanzierenden Klasse eingetragen.



Danke an Alle die mithalfen, den ein oder anderen Stolperstein aus dem weg zu räumen.


Joachim