Seite 1 von 1

MDI-Fenster schließen???

Verfasst: 22. Juni 2009 12:54
von graythornAK
Ich habe eine MDI-Anwendung in der ich subwindows wie folgt einfüge:

myView *pChild = new MyView;
m_pMdiArea->addSubWindow(pChild);


Leider ist MyView extrem resourcenintensiv, also gibt es einen Button irgendwo in einem Dialog, mit dem ich das aktive MDI-Subwindow schließen kann.

Fragen:
Wie schließe ich ein gerade aktives subwindow, so das alle Resourcen frei gegeben werden.
Muß ich vorher die close-Methode aufrufen?

Im Moment mache ich folgendes, bin mir aber über die Konsequenzen nicht ganz im klaren:

void Hydraca::OnFileClose()
{
// aktives subwindow holen
QMdiSubWindow *pMDI = m_pMdiArea->activeSubWindow();

// aktives MyView holen, ist im aktives subwindow drin
HydracaView *pView = GetActiveMyView();

if ((pMDI != NULL) && (pView != NULL))
{
m_pMdiArea->removeSubWindow(pMDI);
delete pView;
}
} // Hydraca::OnFileClose


Im obigen Beispiel rufe ich erst removeSubWindow und danach delete auf. Ist diese Reihenfolge eigentlich korrekt? Das Programm funktioniert, aber es sind ja zwei Szenarien denkbar:
1) removeSubWindow löscht irgendwann auch MyView, aber der delete-AUfruf kommt meistens vorher (ist also eine Frage der Zeit bis das Programm abstürzt.
2) ich rufe erst delete, das subwindow bemerkt, das das MyView gelöscht wurde und reagiert entsprechend.

Anders gefragt, wie sieht der Mechanismus des Fenster schließens/löschens in MDI-Applikationen allgemein aus?

Danke und Gruß
Andreas

Verfasst: 22. Juni 2009 19:17
von solarix
zuerst was grundsätzliches: wenn du in einem Slot die Instanz löschst, welche das zum Slot verbundene Signal auslöst (z.B. durch den "Schliessen"-Button), musst du "deleteLater()" nehmen (nehm ich bei QObject-Instancen grundsätzlich lieber).

IMHO übernimmt das SubWidget das eingebettete Widget, daher sollte:

Code: Alles auswählen

void Hydraca::OnFileClose()
{
  // aktives subwindow holen
  QMdiSubWindow *pMDI = m_pMdiArea->activeSubWindow();

  if (pMDI) {
    m_pMdiArea->removeSubWindow(pMDI);
    pMDI->deleteLater();
  }
}
vollauf genügen. Das kannst du ja gut prüfen, in dem du schnell in den Destruktor von "HydracaView" ein 'qDebug() << "HydracaView zerstoert!"' einfügst und die Programmausgabe nach "deleteLater()" beobachtest...

Verfasst: 22. Juni 2009 19:52
von upsala
Du könntest für dein Mdi-Widget aus das Qt::WA_DeleteOnClose-Flag setzen und dann wenn du das Widget nicht mehr brauchst ein close() darauf aufrufen. Hätte den Vorteil, daß das closeEvent() ausgeführt wird und dieses bei Bedarf wieder abrechen kannst.