Seite 1 von 1

QMdiSubWindow

Verfasst: 3. August 2011 14:47
von janmerkschien
hey ich habe wieder mal ein problem . . .
und zwar mit dem Subwindows von meiner mdiarea.
ich würde denen gerne einen close butten geben aber die schließen halt immer nur das widget und nicht das subwindow.
ich habe jetzt im i-net das hier gefunden:
http://developer.qt.nokia.com/forums/viewthread/6577
nur wenn ich das in meinem code schreibe öffnet sich nur das subwindow ganz ohne widget -.-
muss ich da noch was anderes im code verändern??

Re: QMdiSubWindow

Verfasst: 3. August 2011 15:27
von archer
Was ist denn bei Dir das Widget und was das Subwindow?
Verstehe deine Frage nicht so ganz.

Re: QMdiSubWindow

Verfasst: 4. August 2011 09:45
von janmerkschien
mein subwindow:

Code: Alles auswählen

     table *child = new table;
     QMdiSubWindow *sw = new QMdiSubWindow;
     sw = mdiArea->addSubWindow(child);
     sw->resize(600,400);
     child->show();
und als windget habe ich "table" bezeichnet . .
und table beinhaltet einfach nur ein layout
mit einem closebutton:

Code: Alles auswählen

 connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));
aber dann wird immer nur das table geschlossen und das sw bleibt

Re: QMdiSubWindow

Verfasst: 4. August 2011 10:05
von archer
Du erzeugst hier ein Objekt das du nicht nutzt und irgendwo im Speicher herumschwirrt.

Code: Alles auswählen

QMdiSubWindow* sw = new QMdiSubWindow; 
sw = mdiArea->addSubWindow(child); 
besser wäre

Code: Alles auswählen

QMdiSubWindow* sw = mdiArea->addSubWindow(child); 
Und wenn du close() nur auf dein child machst, warum sollte sich sw dann schließen?

Re: QMdiSubWindow

Verfasst: 4. August 2011 10:19
von janmerkschien
wie kann ich denn ein close auf das subwindow machen?

Re: QMdiSubWindow

Verfasst: 4. August 2011 10:33
von archer
Ein QMdiSubWindow ist auch nur ein Widget und hat damit auch die Methode close().
Steht so in der Doku.

Warum brauchst du denn einen extra closeButton? Du kannst doch auch das SubWindow über
den closeButton in der Titelzeile schliessen.

Re: QMdiSubWindow

Verfasst: 4. August 2011 10:34
von franzf
Kommt jetzt drauf an, in wie weit dein table generisch verwendebar bleiben soll, also auch außerhalb der MdiArea.
Eine elegante Lösung dürfte sein, das closeEvent von table abzufangen (installEventFilter) und dann im eventFilter mdiArea->removeSubWindow aufzurufen (das QCloseEvent musst du ignorieren).
Wenn du das wirklich nur in der mdiArea haben willst, übergib dem Konstruktor von table ein QMdiArea* mdi, speicher es ab, dann kannst du direkt im closeEvent dich selbst entfernen. Oder ein eigenes SIGNAL emittieren, wenn der Button gedrückt wird, damit dein MainWindow drauf reagieren kann, um es aus der MdiArea zu entfernen (hier den click nicht mehr auf close() connecten).

// edit:
archer hat geschrieben:Warum brauchst du denn einen extra closeButton? Du kannst doch auch das SubWindow über
den closeButton in der Titelzeile schliessen.
Das hab ich mich auch gefragt. Könnte sein, weil der das Widget auch mal als eigenes Fenster ohne MDIArea laufen lassen will, oder als Dialog (wenngleich es eigentlich immer eine Window-Deko gibt, die auch einen "close"-Knopf hat).

Re: QMdiSubWindow

Verfasst: 4. August 2011 11:08
von janmerkschien
ich versuche deinen 2ten vorschlag zu realisieren.
jetzt habe ich im konstruktor von table das QMdiArea eingebaut aber jetzt bekomme ich ne fehlermeldung . .
hier die zeilen:
mainwondow.cpp

Code: Alles auswählen

QMdiSubWindow *sw = mdiArea->addSubWindow(new table(QMdiArea* mdiArea));
hier bekomme ich diese fehlermeldung:
expected primary-expression before '*' token

table.cpp

Code: Alles auswählen

table::table(QMdiArea *parent):
    QWidget(parent)
{
       QMdiArea ma = parentWidget(); // zum speichern der MdiArea
table.h

Code: Alles auswählen

public:
    table(QMdiArea *parent = 0);

Re: QMdiSubWindow

Verfasst: 4. August 2011 11:25
von franzf

Code: Alles auswählen

QMdiSubWindow *sw = mdiArea->addSubWindow(new table(QMdiArea* mdiArea));
Und was wundert dich an der Fehlermeldung? QMdiArea* area ist eine Deklaration, es wird aber ein Wert/Objekt/... (hier: Zeiger auf QMdiArea) erwartet.

Code: Alles auswählen

table::table(QMdiArea *parent):
    QWidget(parent)
{
       QMdiArea ma = parentWidget(); // zum speichern der MdiArea
parentWidget() gibt was zurück? Sicher keine QMdiArea. Und warum nicht gleich das parent nehmen, das übergeben wird?
Ich würde mich später auch nicht drauf verlassen, dass parentWidget() wirklich das QMdiSubWindow zurück gibt. Du könntest dich durch alle parents hangeln, und immer mit inherits() prüfen, ob ein QMdiSubWindow vorliegt.
Die Basisinitialisierung "QWidget(parent)" hat auch nicht so viel Sinn, da nach dem Einfügen in die MdiArea wieder ein anderes parent gesetzt wird.

Re: QMdiSubWindow

Verfasst: 4. August 2011 11:33
von janmerkschien
QMdiSubWindow *sw = mdiArea->addSubWindow(new table(*mdiArea));
wäre das denn jetzt richtig?

Re: QMdiSubWindow

Verfasst: 4. August 2011 11:46
von archer

Code: Alles auswählen

QMdiSubWindow *sw = mdiArea->addSubWindow(new table(mdiArea));

Re: QMdiSubWindow

Verfasst: 4. August 2011 12:07
von janmerkschien
ok soweit so gut . . .
nur wenn ich jetzt den button drücke:

Code: Alles auswählen

connect(quitButton, SIGNAL(clicked()), parent, SLOT(close()));
wird die mdiarea geschlossen ist ja klar die übergebe ich ja auch . .
aber wie komm ich jetzt an das subwindow`?

Re: QMdiSubWindow

Verfasst: 4. August 2011 12:57
von janmerkschien
okay danke an alle habs hinbekommen :)

Re: QMdiSubWindow

Verfasst: 4. August 2011 13:04
von archer
Also, ich würde an deiner Stelle in deinem table ein signal anlegen

Code: Alles auswählen

signals:
    void closeTable();
im cpp ein connect

Code: Alles auswählen

connect(quitButton, SIGNAL(clicked()), this, SIGNAL(closeTable()));
und beim Erzeugen deiner table und des mdiSubWindow

Code: Alles auswählen

table* pTable = new table;
QMdiSubWindow *sw = mdiArea->addSubWindow(pTable);
connect(pTable, SIGNAL(closeTable()), sw, SLOT(close()));
Dann brauchst du keine Zeiger weitergeben.

Re: QMdiSubWindow

Verfasst: 4. August 2011 13:10
von janmerkschien
ich hab jetzt beim erzeugen der tabelle nicht die mdiarea übergeben sondern das subwindow und dann kann ich das ganz einfach mit nem close in der table.cpp schließen :)

Code: Alles auswählen

QMdiSubWindow *sw = new QMdiSubWindow(mdiArea);
     sw->setWidget(new table(sw));
     sw->setAttribute(Qt::WA_DeleteOnClose);
     mdiArea->addSubWindow(sw);
     sw->show();

Code: Alles auswählen

connect(quitButton, SIGNAL(clicked()), parent, SLOT(close()));