Zwei Fragen zu QT

Alles rund um die Programmierung mit Qt
Antworten
Tantalus
Beiträge: 2
Registriert: 22. September 2004 15:03
Kontaktdaten:

Zwei Fragen zu QT

Beitrag von Tantalus »

Also ich hab angefangen Qt zu lernen ,da ist mir aufgefallen, dass für die widgets immer mit new Speicher reserviert wird, aber nicht mit delete wieder freigegeben wird.
Warum muss dieser bei qt nicht wieder freigegeben werden??


Meine zweite Frage ist, müsste bei diesem Beispiel nich eine so genannte Endlosschleife auftreten, da das Signal farbeGeaendert(int,int) die methode rgbNeueFarbe(int,int) auslöst , welche wiederum die methode aktualisiereSchiebeLCD(int) aufruft und die methode aktualisiereSchiebeLCD(int) wierderum sendet das Signal farbeGeandert(int,int)
(Signal farbeGeandert(int,int)->rgbNeueFarbe(int,int)->aktualisiereSchiebLCD(int)->Signal fabeGeandert(int,int)->...).
Hier das Beispielprogramm aus meinem Buch.
#include <qapplication.h>
#include <qpushbutton.h>
#include <qslider.h>
#include <qlcdnumber.h>
#include <qlabel.h>
#include <qerrormessage.h>
//........................................................ Klasse SchiebLCD
class SchiebLCD : public QWidget {
Q_OBJECT // notwendig, da eigene Slots enthalten sind
public:
SchiebLCD(int oben, int nr, QWidget *parent, const char* text)
: QWidget(parent, text) {
nummer = nr;
//................ Erzeugen eines Text-Labels
QLabel* name = new QLabel( this );
name->setText( text );
name->setGeometry( 1, 10, 15, 30 );
//................ Erzeugen eines Schiebebalken
schiebbalk = new QSlider( 0, oben, // min-/max-Wert
1, 0, // Schrittweite u. Startwert
QSlider::Horizontal, this ); // Ausrichtung u. Elternwidget
schiebbalk->setGeometry( 20, 10, 200, 30 );
//................ Erzeugen einer LCD-Anzeige
lcdzahl = new QLCDNumber( 3, this ); // maximal 3 Ziffern
lcdzahl->setGeometry( 220, 10, 60, 30 );
lcdzahl->display( 0 );
//................ Verbinde Schiebebalken und LCD-Anzeige
QObject::connect( schiebbalk, SIGNAL( valueChanged( int ) ),
this, SLOT( aktualisiereSchiebLCD( int ) ) );
}
signals:
void farbeGeaendert( int nr, int wert );
public slots:
void aktualisiereSchiebLCD( int wert ) {
schiebbalk->setValue( wert );
lcdzahl->display( wert );
QErrorMessage *meldung = new QErrorMessage(this);
meldung->message("Test");
emit farbeGeaendert( nummer, wert ); // Signal farbeGeaendert schicken
}
private:
int nummer;
QSlider* schiebbalk;
QLCDNumber* lcdzahl;
};
//...................................................... Klasse farbeRgbHsv
class farbeRgbHsv : public QWidget {
Q_OBJECT // notwendig, da eigene Slots enthalten sind
public:
farbeRgbHsv( QWidget *parent ) : QWidget( parent ) { //... Konstruktor
int i;
//................ Initialisierungen
for ( i=0; i<3; i++)
rgbFarbe = 0;
//................ Erzeugen einer Farbanzeige
farbAnzeige = new QLabel( this );
farbAnzeige->setGeometry( 330, 30, 200, 370 );
//................ Erzeugen von drei Schiebealken fuer RGB
const char * rgbText[] = { "R", "G", "B" };
for ( i=0; i<3; i++ ) {
rgb = new SchiebLCD( 255, i, this, rgbText );
rgb->setGeometry( 10, 30+i*50, 300, 60 );
QObject::connect( rgb, SIGNAL( farbeGeaendert( int, int ) ),
this, SLOT( rgbNeueFarbe( int, int ) ) );
}
//................ Erzeugen von drei Schiebealken fuer HSV
const char * hsvText[] = { "H", "S", "V" };
for ( i=0; i<3; i++ ) {
hsv = new SchiebLCD( i==0 ? 359 : 255, i+3, this, hsvText );
hsv->setGeometry( 10, 250+i*50, 300, 60 );
QObject::connect( hsv, SIGNAL( farbeGeaendert( int, int ) ),
this, SLOT( hsvNeueFarbe( int, int ) ) );
}
rgb[0]->aktualisiereSchiebLCD( 255 ); // FЭr Farbenanzeige (rot) zu Beginn
}
public slots:
void rgbNeueFarbe( int nr, int wert ) { //... rgbNeueFarbe
if ( rgbFarbe[nr] != wert ) {
int h, s, v;
rgbFarbe[ nr ] = wert;
QColor neueRgbFarbe( rgbFarbe[0], rgbFarbe[1], rgbFarbe[2] );
farbAnzeige->setPaletteBackgroundColor( neueRgbFarbe );
neueRgbFarbe.getHsv( &h, &s, &v );
hsv[0]->aktualisiereSchiebLCD( hsvFarbe[0] = h );
hsv[1]->aktualisiereSchiebLCD( hsvFarbe[1] = s );
hsv[2]->aktualisiereSchiebLCD( hsvFarbe[2] = v );
}
}
void hsvNeueFarbe( int nr, int wert ) { //... hsvNeueFarbe
if ( hsvFarbe[nr-3] != wert ) {
int r, g, b;
hsvFarbe[ nr-3 ] = wert;
QColor neueHsvFarbe( hsvFarbe[0], hsvFarbe[1], hsvFarbe[2], QColor::Hsv );
farbAnzeige->setPaletteBackgroundColor( neueHsvFarbe );
neueHsvFarbe.getRgb( &r, &g, &b );;
rgb[0]->aktualisiereSchiebLCD( rgbFarbe[0] = r );
rgb[1]->aktualisiereSchiebLCD( rgbFarbe[1] = g );
rgb[2]->aktualisiereSchiebLCD( rgbFarbe[2] = b );
}
}
private:
QLabel *farbAnzeige;
int rgbFarbe[3], hsvFarbe[3];
SchiebLCD *rgb[3], *hsv[3];
};
#include "farbe.moc"
//.................................................................... main
int main( int argc, char* argv[] ) {
QApplication myapp( argc, argv );

farbeRgbHsv* mywidget = new farbeRgbHsv( 0 );
mywidget->setGeometry( 100, 100, 540, 450 );

myapp.setMainWidget( mywidget );
mywidget->show();
return myapp.exec();
}

Wenn man es kompiliert ensteht keine Endlosschleife, aber ich vesteh nicht warum.
Ich hoffe ihr könnt mir helfen.
Goos
Beiträge: 360
Registriert: 17. August 2004 10:10
Wohnort: Black Forest

Beitrag von Goos »

Code: Alles auswählen

void rgbNeueFarbe( int nr, int wert ) { //... rgbNeueFarbe 
if ( rgbFarbe[nr] != wert ) {
...aktualisiereSchiebLCD wird also nur aufgerufen, wenn "wert" einen anderen Wert hat als im vorherigen Durchlauf.

Wegen dem delete.... soweit ich mich erinnern kann macht das QT automatisch, sobald das Parent Objekt weg ist.

Goos
Tantalus
Beiträge: 2
Registriert: 22. September 2004 15:03
Kontaktdaten:

Beitrag von Tantalus »

Danke, ich habe diese if anweisung übersehen und mich die ganze Zeit gewundert.
Heißt das, dass ich bei Qt nie den operator delete benutzen muss, oder muss ich den nur nicht bei objekten die von Qobject abgeleitet sind nicht benutzen??
Goos
Beiträge: 360
Registriert: 17. August 2004 10:10
Wohnort: Black Forest

Beitrag von Goos »

Das heisst, dass du die Anleitung lesen musst ;)
http://doc.trolltech.com/3.3/objecttrees.html
Antworten