QWidget als Parameter in Funktion übergeben

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
WilliamSpiderWeb
Beiträge: 14
Registriert: 2. März 2011 23:14

QWidget als Parameter in Funktion übergeben

Beitrag von WilliamSpiderWeb »

Ich beschreibe mein Problem am besten direkt an Hand einer vereinfachten Form meines Codes.

Auszug aus meinem MainWindow

Code: Alles auswählen

  QDockWidget *m_meinWidget;
  void initDockWidget(QDockWidget *widget, QString sTitle);
  void toggleVisibility(QDockWidget *widget, bool bSwitch);
Im MainWindow Konstruktor erstelle ich das DockWidget neu

Code: Alles auswählen

  initDockWidget(m_meinWidget, "Titel");
Der Inhalt der initDockWidget sieht so aus

Code: Alles auswählen

  widget = new QDockWidget(this, sTitle);
  widget->hide();
An anderer Stelle (zum Beispiel beim Druck auf einem Button) möchte ich das Widget sichtbar machen

Code: Alles auswählen

  toggleVisibility(m_meinWidget, "true");
Inhalt der toggleVisibility

Code: Alles auswählen

  if (bSwitch == "true")
    widget->show();
  else
    widget->hide();
Sobald "widget->show()" aufgerufen wird, stürzt meine App ab mit folgender MessageBox:
Der Prozess wurde nach Erhalt eines Signals vom Betriebssystem angehalten.

Name des Signals: SIGSEGV
Bedeutung: Segmentation fault
Ich hab zwar schon im meinem QT Buch das Kapitel "Speicherverwaltung von Objekten" durchgelesen, weiß aber trotzdem nicht, was ich hätte anders machen sollen.

Ich denke, dass ich bei der Übergabe des Pointers auf das DockWidgets in die toggle-Funktion etwas falsch mache, denn, wenn ich in der "initDockWidget" nach dem "hide()" die Methode "isVisible()" aufrufe, bekomme ich ein "false" zurück.
Rufe ich "isVisible" aber in der "toggleVisibility()" vor dem "show()" auf, bekomme ich ein "true" zurück.

Bitte um Hilfe.[/code]
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Dein uninitialisierter Pointer zeigt am Anfang irgendwo hin. Du übergibst jetzt den Pointer als Kopie. Das new in der Funktion wirkt sich nur auf diese Kopie aus, das Original (dein Member) zeigt weiterhin irgendwo hin (wenn du brav warst hast du den Pointer im Konstruktor mit NULL initialisiert).
Lösung:
* Pointer auf Pointer übergeben:

Code: Alles auswählen

void func(QDockWidget** w) {
    *w = new QDockWIdget();
}
* Als Referenz

Code: Alles auswählen

void func(QDockWIdget*& w) {
    w = new QDockWIdget();
}
* Du bist doch eh in ner Memberfunktion. Warum packst du das Initialisieren aller QDockWidgets nicht in EINE Funktion, und greifst dort DIREKT auf die Member zu:

Code: Alles auswählen

void initDocks() {
    m_dockA = new QDockWidget();
    m_dockA->hide();
    m_dockB = new QDockWidget();
    m_dockB->hide();
    m_dockC = new QDockWidget();
    m_dockC->hide();
    // usw.
}
Die zusätzliche Mini-Funktion spart nicht wirklich viel Schreibarbeit, und sorgt (wie du schon gesehen hast) für zusätzlivhes Fehlerpotential (wenn man nicht weiß was man macht :P).

* ALternativ kannst du das SPeichern der Pointer als Member komplett bleiben lassen, und nur über findChild() nach Bedarf das entsprechende DockWidget holen.
WilliamSpiderWeb
Beiträge: 14
Registriert: 2. März 2011 23:14

Beitrag von WilliamSpiderWeb »

Erstmal danke.
Der Tip mit der Referenz war Hilfreich.
Damit funktioniert's einwandfrei.

Zu der Frage, warum ich mir die kleine Hilfsfunktion baue...
Wie in meinem Thread beschrieben, habe ich nur eine vereinfachte Version meines Codes gepostet. In dieser Hilfsfunktion führe ich die gesamte Konfiguration der Widgets durch.
Antworten