Zeiger auf Widget übergeben

Alles rund um die Programmierung mit Qt
Antworten
oberschlingel
Beiträge: 85
Registriert: 11. April 2006 09:25
Wohnort: Berlin

Zeiger auf Widget übergeben

Beitrag von oberschlingel »

Mal eine blöde Frage:
Ich habe ein QMainWindow, hier erzeuge ich z.B. zwei Widgets (abgeleitete Widget-Klassen).
Widget 1 soll bei Bedarf als CentralWidget angezeigt werden und wenn nicht, wird das ganze Widget gelöscht (es ist für die Anwendung wichtig, dass das Widget nicht nur unsichtbar wird).
Widget 2 ist ein Logger, diesen übergebe ich als Zeiger an den Kontruktor von Widget 1, denn der Logger soll innerhalb von Widget 1 angezeigt werden. Ziel ist es, den Logger und seinen Inhalt unverändert zu lassen und wieder anzuzeigen, wenn das Widget 1 wieder neu erzeugt wird.

Irgendwie kommt da aber nur Mist raus, sobald ich mehrmals Widget 1 erstelle und dann lösche. Wenn ich aber vor jedem neuen Erzeugen von Widget 1 auch den Logger (Widget 2) neu erzeuge, dann geht es.

Verstehe ich etwas falsch? Wenn Widget 1 mit delete gelöscht wird, sollte doch eigentlich nur der Zeiger auf mein Logger-Widget gelöscht werden und nicht das Objekt selbst, oder? Und wie könnte ich das umgehen?

Hier nochmal in Form von Pseudocode:

Das geht nicht:

Code: Alles auswählen

// In Klasse QMainWindow
QWidget2 *qwidget2 = new QWidget2(this);
QWidget1 *qwidget1 = new QWidget1(qwidget2, this); // Das geht

delete qwidget1;
QWidget1 *qwidget1 = new QWidget1(qwidget2, this); // Hier kommt Mist raus
Das geht, aber qwidget2 verliert seinen Inhalt:

Code: Alles auswählen

// In Klasse QMainWindow
QWidget2 *qwidget2 = new QWidget2(this);
QWidget1 *qwidget1 = new QWidget1(qwidget2, this); // Das geht

delete qwidget1;
QWidget2 *qwidget2 = new QWidget2(this);
QWidget1 *qwidget1 = new QWidget1(qwidget2, this); // geht auch, aber widget2 verliert seinen Inhalt
Danke für eure Hilfe!
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Dein (Pseudo-)Code ergibt überhaupt keinen Sinn.
Chris81T
Beiträge: 82
Registriert: 4. Mai 2008 00:06
Wohnort: Urbar

Beitrag von Chris81T »

Widget 2 ist ein Logger, diesen übergebe ich als Zeiger an den Kontruktor von Widget 1, denn der Logger soll innerhalb von Widget 1 angezeigt werden
Also wenn du nix besonderes mit dem übergebenen Zeiger im ctor von Widget1 machst, sondern einfach die Qt eigene Parent-Beziehung setzt, widerspricht sich deine Aussage!

Denn sogesehen wäre Widget2 das Parent von Widget1. An dass wiederum bedeutet, dass Widget1 im Bereich von Widget2 angezeigt wird. Nicht anders rum!
oberschlingel
Beiträge: 85
Registriert: 11. April 2006 09:25
Wohnort: Berlin

Beitrag von oberschlingel »

Danke für eure Antworten.

Aber wie gehe ich dann vor? Widget 2 ist im Layout von Widget 1 eingebunden. Speichere ich dann einfach einen Zeiger auf parent und binde darüber Widget2 ein, das im QMainWindow erstellt wurde? Also etwa so:

Code: Alles auswählen

Widget1::Widget1(QWidget *parent) {
this->myParent = parent;
this->setLayout();
}

Widget1::setLayout() {
...
layout->setWidget(myParent->widget2);
}
DANKE!
Chris81T
Beiträge: 82
Registriert: 4. Mai 2008 00:06
Wohnort: Urbar

Beitrag von Chris81T »

Sorry, aber so ganz versteh ich die Behandlung nicht, bzw. finde sie nicht sinnvoll.

Was mein ich damit:

Ich gehe mal von aus, dass deine Widget1 Klasse von QWidget erbt?!

Dann solltest du zum einem schon einmal beachten, dass der QWidget ctor einen Parent erwartet (ist nicht zwingend). Warum übergibst du nicht deinen Param parent an den ctor von QWidget?! (Schau in der Doku mal nach: ctor QWidget)

Aber zu deiner Aufgabenstellung:

- Widget1 wird erstellt (hat zB. als Parent dein QMainWindow)
- Widget2 wird erstellt und wird Kind von Widget1

- Widget1 soll zerstört werden, Widget2 soll weiterhin existieren und daraufhin soll ein neues Widget1 leben was das bestehende Widget2 aufnimmt:
Nun gut, spricht ja nix dagegen, vor dem Löschen von dem bisherigen Widget1 Objekt das neue Widget1 Objekt zu erzeugen und dann dem Widget2 einen neuen Parent (neues WIdget1 Objekt) zuzuweisen (in dass Layout des neuen Widget1 Objekt zuzuordnen)

Das sollte dann funktionieren.


PS: Ich weis ja nicht, was genau Widget1 sein soll, aber vielleicht ist es ja gar nicht notwendig es zu löschen und dann ein neues zu erzeugen?! Event. lässt sich ja ein "reset" bewerkstelligen?! Aber wie gesagt, ich weis ja net, was du vorhast. Im diesen Sinne viel Erfolg 8)
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Da du uns bisher noch nicht wirklich brauchbaren Code (== kompierbares Minimalbeispiel, das deinen Fehler enthält) gepostet hast, kann man nur raten.
Mein Tip:
1) NIEMALS NIE ein Widget in mehreren Widgets anzeigen versuchen! Es werden die childs gelöscht. Auch wenn du dir selber eine Krücke bastelst mit nem myParent, anstatt endlich die Qt-Funktionen zu nutzen (-> Basisinitialisierung/Initialisierungsliste als C++-Standard-Begriff für dich zum nachlesen).
Sobald du das Widget in ein anderes Layout packst hat das Ding einen neuen parent. Am Ende löschst du das selber dann machts PENG SEGFAULT.

2) Poste bitte endlich Code, wie er auf deinem Rechner liegt, nicht zusammengestöppselten Code, der keine einzige relevante und nachvollziehbare Zeile enthält und so auch gar nicht kompilieren wird (setLayout() braucht nen Parameter, setWidget in deiner Anwendung gibt es in keiner Qt-Layout-Klasse).
oberschlingel
Beiträge: 85
Registriert: 11. April 2006 09:25
Wohnort: Berlin

Beitrag von oberschlingel »

Lieber Chris81T, danke für Deine Mühe. Kaum zu glauben. Und langsam hilfst Du mir, endlich dieses "parent"-System zu begreifen.

Allerdings hätte ich noch eine Frage, zuerst erkläre ich Dir aber warum ich das ganze so mache.

Im QMainWindow ist ein QStackedWidget untergebracht. Hier drin befinden sich einige weitere QWidets, die verschiedenes anzeigen und sich umschalten lassen. Jetzt kommt es vor, dass ich ein Widget vom "Stack" entferne (removeWidget()) und das Widget anschließend lösche (delete). Und ggf. wenn es wieder gebraucht wird, erzeuge ich es neu und bringe es wieder im StackWidget unter. Kann gut sein, dass es in diesem Fall besser wäre, das Widget nie zu löschen, aber ich hatte da mal an die Resourcen gedacht...

Das ganze System ist nun noch ans Netzwerk gebunden und kann ggf. Textnachrichten empfangen. Um diese anzuzeigen, habe ich ein Klasse (erbt von QWidget) geschrieben, die wiederum ein formatiertes QTextEdit anzeigt und ggf. füllt. Über Slots ist die Klasse mit dem ganzen Netzwerk-Kram verbunden.

Die Klasse, ich nenne sie mal ChatWidget, möchte ich nun verschiedenen Widgets auf dem StackedWidget mitgeben und dort anzeigen. Der Inhalt vom Chat soll immer der gleiche bleiben. Und ich möchte Widgets vom Stack löschen und wiederanlegen können, und ihnen dabei das ChatWidget erneut mitgeben. Die Widgets wiederum binden das ChatWidget in einem eigenen Layout ein.

Und das wiederum wirft für mich eine neue Frage auf:

Ich verstehe jetzt, dass ich in meinem MainWindow einmal das StackedWidget (mit Parent MainWindow) erstelle, außerdem die Klassen WidgetX für das Stack (mit Parent MainWindow), die ich dann dem StackWidget zuweise. Jetzt erstelle ich im MainWindow auch noch die Klasse ChatWidget ohne Parent. Den Parent von ChatWidget setze ich dann individuell über setParent() und weise das gerade angezeigte WidgetX zu.

Wie aber kann ich nun aus WidgetX auf das ChatWidget zugreifen, und zwar nur, um das ChatWidget jeweils in das Layout von WidgetX einzubinden???

Oder ist mein Ansatz mal wieder totaler Müll?


Herzlichen Dank.
oberschlingel
Beiträge: 85
Registriert: 11. April 2006 09:25
Wohnort: Berlin

Beitrag von oberschlingel »

Lieber Franz,

danke auch Dir, Punkt 1 ist sehr interessant.

Dann wäre es für mich wohl besser, ein übergeordnetes Widget im MainWindow zu erstellen, dass das StackedWidget und das ChatWidget enthält. Somit gibt es das ChatWidget nur einmal. Ist das ein besserer Ansatz?

Danke!
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

oberschlingel hat geschrieben:Die Klasse, ich nenne sie mal ChatWidget, möchte ich nun verschiedenen Widgets auf dem StackedWidget mitgeben und dort anzeigen. Der Inhalt vom Chat soll immer der gleiche bleiben.
Wie ich mir gedacht habe. Mach das nicht.
Schreib dir eine Klasse (von QObject abgeleitet, wir brauchen hier noch keine grafische Repräsentation), die Signals bei neu eingetroffenen Nachrichten aussendet, und connecte dein ChatWidget an dieses SIGNAL. Dann erstellst immer ein neues ChatWidget-Objekt für deine einzelnen Widget-Instanzen! Du verwendest eine gemeinsame Datenquelle (nennen wir sie ChatMessageQueue). Da existiert für jeden Account (oder was du willst) genau EIN Objekt. Damit gehst du sicher, dass jedes Widget mitbekommt, wann neue Nachrichten eintreffen, und alle zeigen auch immer das gleiche an.
oberschlingel
Beiträge: 85
Registriert: 11. April 2006 09:25
Wohnort: Berlin

Beitrag von oberschlingel »

Tausend Dank für eure Hilfe. Jetzt funktioniert es!
Antworten