QT Dialog Extension auch unter QMainWindow?
-
Hallo zusammen,
ich habe Frage zu der Dialog Extension, komme nicht weiter und finde auch im Netz nichts darüber.
Ersteinmal zur Dialog Extension: Auch mit dem QT Designer erstellte Dialoge sind nach dem Extension Example wunderbar einzubinden und funktionieren (also ein kleiner Dialog mit einem Button, der dann den erweiterten Dialog aufklappt und auch wieder zuklappt).
Jetzt würde ich das aber gerne in einem QMainWindow machen.
Das Problem: Diese Funktionalität ist nur in QDialog vorhanden (also die Member, Properties, etc.).Ich kann in QMainWindow dennoch eine Extension plazieren, darstellen und wieder verstecken, etc. Die Fenstergröße ändert sich, wenn ich das Widget darstelle, aber das Fenster verkleinert sich nicht, wenn ich das Widget wieder rausnehme. Es ist auch über save/restoreGeometry(), resize(), etc. nicht möglich, die Fenstergröße wieder zu verkleinern (vergrößern geht, verkleinern geht erst zu einem späteren Zeitpunkt).
Ui::Test::Test(QWidget *parent, Qt::WFlags flags) : QMainWindow(parent, flags) { setupUi(this); Ext = new Extend(this); // Geo = saveGeometry(); gridLayout->addWidget(Ext); connect(ExtendButton, SIGNAL(toggled(bool)), Ext, SLOT(setVisible(bool))); Ext->hide(); }
void Ui::Test::ExtendSlot(bool State) { if(State == true) { this->ExtendButton->setText("Less"); } else { this->ExtendButton->setText("More"); // this->restoreGeometry(Geo); } }
Ich habe hier quasi noch ein zweites Signal verbunden, um den Buttontext zu ändern und würde hier auch gerne die Fenstergröße zurücksetzen. Das geht nicht in einem Aufwasch. Wenn ich nun das restoreGeometry() oder resize() mit einem anderen Knopf verbinde, den ich später drücke, dann wird das Fenster wieder kleiner.
Es sieht so aus, als ob das Widget erst nach einiger Zeit wirklich aus dem Fenster genommen wurde (obwohl es auch sofort und VOR dem resize() verschwindet). Und, wie schon geschrieben, ein weiteres vergrößern geht zu diesem Zeitpunkt im Code.
Weiß jemand, wie ich das Problem einigermaßen elegant lösen kann?
-
Und warum nicht setVisible() in dem ExtendSlot machen, und eben das toggled(bool) nur auf ExtendSlot connecten?
Dann könnte ExtendSlot ungefähr so ausschauen:Test::ExtendSlot(bool State) { if(State) { lessSize = size(); this->ExtendButton->setText("Less"); Ext->show(); // == setVisible(true) } else { this->ExtendButton->setText("More"); Ext->hide(); // == setVisible(false) resize(lessSize); } }
Außerdem:
Deine Klasse Test liegt im namespace Ui?!? Das kann böse Konflikte mit den von uic generierten Klassen geben, denn die liegen dann auch in dem namespace.
Oder bearbeitest du die generierten Sourcen selber? Das ist VERBOTEN! (Ok, etwas hart formuliert, aber das dicke Warning im Header sollte man schon gelesen haben, denn beim nächsten Lauf von Uic werden deine Änderungen überschrieben...
-
Das habe ich alles schon versucht. Es ändert nichts. Egal, ob mit setVisible() in meinem Slot, mit show()/hide(). Ich kann so ja auch den obigen connect() komplett weglassen und alles in meinem Slot ablaufen lassen - es ist immer das gleiche Ergebnis.
Zu den Namespaces: Natürlich bearbeite ich die generierten Sourcen nicht selbst. Bei mir liegen auf die Art nun Ui_class und class in einem Namespace. Bisher keine Probleme. Wenn es Probleme geben sollte, dann ändere ich das, aber die Klassen haben ja unterschiedliche Namen, also sollte es da keine Konflikte geben.
-
Also nochmal zusammengefaßt:
Die Funktionalität ist in QDialog, aber nicht in QMainWindow vorhanden. Also wird QMainWindow auch nie selbständig das Fenster wieder verkleinern. Meine Versuche, das Fenster zu verkleinern scheitern jedoch, da wohl intern noch die "Extended-Größe" als Minimum angenommen wird. Es macht keinen Unterschied, ob ich das alles in einem eigenen Slot oder in getrennten Slots ausführe. Die Größe läßt sich auch nicht nach unten ändern, wenn ich das Widget entferne oder zerstöre. Erst NACH dem Verlassen des Slots kann ich beliebig in einem Event, Slot, etc. mein resize durchführen. Jedoch kann ich in dem Slot eine Vergrößerung durchführen. Also ist das resizen im Allgemeinen nicht geblockt.Also wenn ich z.B. einen Button mit einem Slot verknüpfe, der die Verkleinerung durchführt, dann funktioniert das.
Da ich nun sicher nicht anfangen sollte, QMainWindow von QDialog beerben zu lassen ist die Frage bekomme ich "zeitnah" (Unwort, ich weiß) einen resize hin - ohne noch weitere Slots, Timer, oder was auch immer einzubauen (wäre ja auch keine garantierte Lösung).
Falls es jemanden interessiert, kann ich gerne den gesamten Beispielcode posten.
Und nochmal zu den Namespaces:
Ich habe hier z.B.
Ui_ExtendClass (vom QT Desinger erzeugt)
ExtendClass (vom Designer mittels namespace umbenannt)
Extend (meine Klasse)Das ganze wiederholt sich für weitere Klassen (natürlich nur GUI-Klassen). Die Namespaces nutze ich immer explizit und "using namespace" verwende ich sowieso nie. Also dürfte es hier sicher zu keinen Problemen mit dem Namensraum kommen. Falls doch und ich verstehe hier etwas nicht oder übersehe einfach etwas - bitte rückt mir den Kopf zurecht :p.
Dazu muß ich noch sagen, daß ich wirklich ein Problem mit den Klassen (nicht mit den Namespaces) bekommen hatte, nachdem ich forward referenzen eingebaut hatte. Da bei einem Standardprojekt nicht von der Ui_class mitgeerbt wird, sondern ein Pointer auf die Klasse verwendet wird, kommt es da unter besonderen Umständen wirklich zu einem Heap-Problem. Wenn man das ändert und immer multiple inheritance macht, passiert das nicht. Das schaue ich mir noch genauer an und werde dann eventuell einen Bug-Report basteln (scheint wirklich ein Bug zu sein).
-
Ok, hab mir jetzt mal dieses Extension-Beispiel angeschaut.
Dass die Funktionalität nur in QDialog zur Verfügung steht, ist eine eindeutige Fehlinforamtion :p Denn das resizen übernimmt das Layout. Und wenn du dir jetzt eine "besondere" Operation auf einem QLayout suchst fällt einem das hier ins Auge:QGridLayout *mainLayout = new QGridLayout; mainLayout->setSizeConstraint(QLayout::SetFixedSize);
Nun braucht man nur noch eine Besonderheit von QMainWindow zu beachten. Diese Klasse verwendet ein eigenes Layout, so wg. MenuBar, ToolBar, DockWidgets usw. setLayout ist überschrieben, dass man kein eigenes Layout setzen kann. Eigenen content platziert man im centralWidget().
Die Lösung ist nun klar:mainWindow->layout()->setSizeConstraint(QLayout::SetFixedSize);
Und schon wird automatisch das Fenster in der Größe angepasst.
Nachteil: Du kannst die Fenstergröße nicht mehr händisch verändern. Wenns dich nicht stört hast du jetzt deine Lösung.
-
Öhm wow
Ich bin jetzt nicht vor dem Rechner, kann es mir also erst später ansehen. Ist dieser Constraint aber nicht der, den ich auch im QT Designer setze? Wohl nicht, denn da setze ich ja für's CentralWidget bzw. dessen Layout.
Ich schaue mir das an und danke - so oder so - für Deine Aufmerksamkeit und Hilfe
-
Heureka!
Genau so funktioniert es! Und das meinte ich mit "eleganter Lösung"
Ich hatte überall FixedSize gesetzt, wo ich es fand. Nur bin ich auch nach mehrtägigen Versuchen nicht darauf gekommen, mal beim MainWindow zu schauen, da ich dachte, das hätte ich im Designer schon eingestellt. Ich hatte mich die ganzen Tage mit den Layouts, Hints, etc. auseinandergesetzt.Und selbst diese Einstellung könnte ich ja nun in einem Slot vornehmen und wäre dann nicht auf ein fixed size Fenster limitiert (was aber in meinem Fall nicht wichtig ist).
Vielen Dank nochmal