[gelöst]Grundverständnis Zeiger

Alles rund um die Programmierung mit Qt
Antworten
-marcelp-
Beiträge: 36
Registriert: 12. Januar 2007 09:00
Kontaktdaten:

[gelöst]Grundverständnis Zeiger

Beitrag von -marcelp- »

Hallo,

ich schreibe eine Adressverwaltung mit zwei Fenstern. Das erste enthält eine Übersichtstabelle und auch eine Funktion zum Refresh dieser.
Das zweite Fenster wird aufgerufen, um eine Adresse anzulegen oder zu ändern und soll abschließend die Refreshfunktion aus Fenster 1 aufrufen.
Ich übergebe beim Aufruf von Fenster 2 einen Zeiger "QWidget *ptr = this". Darüber kann ich aber nur auf die Funktionen von QWidget zugreifen.
Die Refreshfunktion meiner von QWidget abgeleiteten Klasse bleibt unbekannt.

Wer löst mein (C++Anfänger-)Problem?

Marcel
Zuletzt geändert von -marcelp- am 17. Oktober 2008 22:48, insgesamt 1-mal geändert.
marco
Beiträge: 41
Registriert: 6. Dezember 2006 23:46
Wohnort: Niederrhein

Beitrag von marco »

Hallo,

also erstmal... am besten postest du mal ein bisschen Code. Dein Problem ist recht allgemein und etwas vage beschrieben und kann sehr viele Ursachen haben, soweit ich das überblicken kann.

Übrigens: Das was du vorhast könnte fast ein Lehrbuchbeispiel für die Verwendung von SIGNAL/SLOTS sein, das solltest du dir also mal anschauen!

Gruß, Marco
Zuletzt geändert von marco am 22. Januar 2007 21:36, insgesamt 1-mal geändert.
Tarek
Beiträge: 46
Registriert: 3. Oktober 2005 14:29
Kontaktdaten:

Beitrag von Tarek »

Hallo,
da gibt es mehrere Möglichkeiten,
  1. Typecasting bzw. das direkte Benutzen des richtigen Zeigertyps. Dazu muss allerdings dem zweiten Fenster die abgeleitete Klasse bekannt sein.
  2. Call-Back (nicht schön). Statt einem Zeiger auf das erste Fenster übergibst du einen Zeiger auf die refresh-Funktion.
  3. Signals & Slots. Du richtest die Refresh-Funktion als Slot ein und verbindest den mit einem Signal deines zweiten Fensters.
-marcelp-
Beiträge: 36
Registriert: 12. Januar 2007 09:00
Kontaktdaten:

Re: Grundverständnis Zeiger

Beitrag von -marcelp- »

Danke erstmal für Eure Hilfe.

Also vielleicht etwas genauer:

Ich habe mit Qt's Designer in KDevelop meine beiden Formulare erstellt und davon abgeleitet. In der Klasse von Form 1 öffne ich Form 2:

void windowmain::adress_insert()
{
adressinput *ai = new adressinput(); //Aufruf Form 2
connect( ai, SIGNAL( ai.pbadrinOK->clicked() ), SLOT( this->adress_refresh() ) );
ai->show();
}

Wenn in Form 2 die Adressbearbeitung erledigt ist, soll die Refreshroutine der Tabelle in Form 1 aufgerufen werden - das passiert aber nicht.
Die connect-Zeile habe ich auf Tareks Hinweis nachträglich eingebaut, läuft so aber auch nicht.

Wenn ich das hier probiere:

void windowmain::adress_insert()
{
adressinput *ai = new adressinput( this ); //Aufruf Form 2
ai->show();
}

habe ich in

articleinput::articleinput( QWidget* ptr, const char* name, WFlags fl ): frmartikeldata(parent,name,fl)
{
}

mit *ptr den Zeiger auf die Basisklasse von Form 1, kann aber nicht auf nachträglich eingebaute Funktionen (wie eben die RefreshTable) zugreifen.
cbrider
Beiträge: 17
Registriert: 8. Juli 2005 00:45

Beitrag von cbrider »

Also mal ein paar Sache die mir so aufgefallen sind.

1.

Code: Alles auswählen

adressinput *ai = new adressinput();
connect( ai, SIGNAL( ai.pbadrinOK->clicked() ), SLOT( this->adress_refresh() ) );
"*ai" is ja nun mal ein Pointer auf ein Objekt der Klasse adressinput und bei solchen werden Methoden und Objekte mit einem "->" angesprochen. Also solltest Du mal

Code: Alles auswählen

SIGNAL( ai->pbadrinOK.clicked() ), 
probieren.

2.
Wenn du innerhalb einer Methode ein Objekt erzeugst (hier das "*ai")

Code: Alles auswählen

void windowmain::adress_insert() 
{ 
adressinput *ai = new adressinput( this ); //Aufruf Form 2 
ai->show(); 
} 
dann gilt dieses Objekt auch nur für die Lebensdauer deiner Methode. Sprich:
- ai erzeugen
- ai->show()
- Methoden Ende
- ai ist futsch.

Besser währe so etwas

Code: Alles auswählen

class windowmain
{

  // ... der Rest deiner Klassendefinition

  private:

    adressinput *ai;
};

void windowmain::adress_insert() 
{ 
ai = new adressinput( this );
ai->show(); 
}

Dann bleibt das Objekt "*ai" über die Laufzeit der Methode "adress_insert()" hinweg gültig.

Ideal währe es auch, wenn du die Initialisierung von "*ai", also das

Code: Alles auswählen

ai = new adressinput( this );
in den Konstruktor der Klasse "windowmain" schreibst.

Hoffentlich Hilfs dir weiter
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Das connect kann so nie funktionieren...
http://doc.trolltech.com/4.2/signalsandslots.html
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Tarek
Beiträge: 46
Registriert: 3. Oktober 2005 14:29
Kontaktdaten:

Beitrag von Tarek »

Denke ich auch, normaler Weise müsste er da auch auf der Konsole einen Fehler anzeigen.

Also richtig wäre es wie folgt:

Code: Alles auswählen

connect(ai->pbadrinOK, SIGNAL(clicked()),this,SLOT(adress_refresh()));
Und "adress_refresh" muss natürlich als slot definiert sein.
-marcelp-
Beiträge: 36
Registriert: 12. Januar 2007 09:00
Kontaktdaten:

Beitrag von -marcelp- »

Also erstmal Danke!

Ich habe Euren Rat befolgt, *ai ausserhalb von adress_insert() erzeugt und im Konstruktor von Form 1 die Verbindung mittels

connect( ai->pbadrinOK,SIGNAL( clicked() ),this,SLOT( adress_refresh() ) );

hergestellt.
Das hat wunderbar geklappt - genau ein mal!

Das Problem: Will ich mein Programm ausführen, öffnet sich kein Formular und in der Kontrollleiste ist kein Programm zu sehen.
Eine testhalber im Konstruktor eingefügte QMessageBox erscheint noch, nehme ich die connect-Zeile wieder raus, funktioniert alles wieder.

Liegt das überhaupt an meinem Code?

Als Info: Ich schreibe unter Kubuntu 6.06 / KDE 3.5.2 / Kdevelop 3.3.2 / Qt 3.3.6

Gruß, Marcel :(
Tarek
Beiträge: 46
Registriert: 3. Oktober 2005 14:29
Kontaktdaten:

Beitrag von Tarek »

Ich habe Euren Rat befolgt, *ai ausserhalb von adress_insert() erzeugt
Also darüber ob es sinnvoll ist den zweiten Dialog im Konstruktor zu erzeugen kann man sich sicher streiten, auf jeden Fall ist es so unter Umständen etwas schwieriger bei mehrfachen Aufrufen alles wieder in den gewünschten Zustand zu versetzen. Wenn du ihn hingegen in der Funktion "adress_insert()" erzeugst bekommst du immer einen "frischen" Dialog.
und im Konstruktor von Form 1 die Verbindung mittels

connect( ai->pbadrinOK,SIGNAL( clicked() ),this,SLOT( adress_refresh() ) );

hergestellt.
Das hat wunderbar geklappt - genau ein mal!

Das Problem: Will ich mein Programm ausführen, öffnet sich kein Formular und in der Kontrollleiste ist kein Programm zu sehen.
Eine testhalber im Konstruktor eingefügte QMessageBox erscheint noch, nehme ich die connect-Zeile wieder raus, funktioniert alles wieder.
Wäre sehr sinnvoll wenn du den Code wie er jetzt ist und den debugger output / backtrace posten würdest. So kann man nur raten...
Hast du vielleicht das connect() vor der Erzeugung des Dialogs aufgerufen?
-marcelp-
Beiträge: 36
Registriert: 12. Januar 2007 09:00
Kontaktdaten:

Beitrag von -marcelp- »

Danke Euch allen, jetzt läuft alles wie gewünscht.
Ich habe die connect-Zeilen im Konstruktor von Form 1 erstellt, ist natürlich Blödsinn.

Tarek, sage mir bei Gelegenheit mal, was Du gerne trinkst...

Gruß, Marcel :D
Antworten