QWidget.resize() und (QWidget) extension.hide()

Alles rund um die Programmierung mit Qt
Antworten
der_andreas
Beiträge: 15
Registriert: 21. August 2006 21:07
Wohnort: Frankfurt am Main

QWidget.resize() und (QWidget) extension.hide()

Beitrag von der_andreas »

Hallo,
beim Versuch ein (Dialog-) Widget mit Erweiterung zu resizen, bekomme ich ein seltsames Verhalten. Das Dialogfeld besitzt einen "more"-Button (btn_more) und einen QFrame (frm_extension) mit darin eingebundenen Slidern, Checkboxen und Push-Buttons. Der QFrame ist in der Grundeinstellung nicht sichtbar ( frm_extension.hide() ). Beim togglen des 'btn_more' sendet dieser ein Signal, welches ich mit einer eigenen Funktion abfange, um den QFrame sichtbar zu machen: 'frm_extension.setVisible(true)'. Jetzt darf aber der aufklappende Frame das darüberliegende Layout nicht verändern, also vergrößere ich vorher das main-Widget mittels resize um die Größe (Höhe) des Frame. Das klappt wie gewollt.
Beim umgekehrten Vorgang zeigt sich jetzt ein seltsames Verhalten:
Im Code sind die notwendigen Schritte in umgekehrter Reihenfolge notiert.
Der Frame wird ausgeblendet, das Fenster wird jedoch nicht kleiner als (fixedHeight_Frame + minimumHeight_Rest)
wenn height_Rest kleiner als (fixedHeight_Frame ist.
Das Layout sieht so aus:

Code: Alles auswählen

#====================================[_][X]
|  <<<<<<<<<<Anzeigeelement>>>>>>>>>>>>>>>>  |    <- Normal View
|  <<<<<<<<<<<<<<<<<->>>>>>>>>>>>>>>>>>>>  |
|_________________________________[ More]__[Quit] |
+-----------------------------------------------------------------------------------------+
| [ ]  [X]  [_____] [________] xxxxxx =====V=======   |         (visible)
| [ ]  [X]  [_____] [________] xxxxxx =====V=======   |    <- Extension Frame
+-----------------------------------------------------------------------------------------+
Der Code im Konstruktor :

Code: Alles auswählen

...     
    extension = new QFrame(this);          // QFrame *extension; im .h file
     extension->setMaximumSize (10000,184);
  ...
    mainLayout->addLayout(normalLayout, 0, 0, 1, 2);
    mainLayout->addWidget(extension,    1, 0, 1, 2);
    setLayout(mainLayout);
    extension->hide();
Der Code im Handler :

Code: Alles auswählen

 void myApp::on_btn_More(bool b)
{
   int w, h, s;
    s = h = this->height();
    w = this->width();
    
    extension->setVisible(b);
    if(b){
        winPos = pos();           // QPoint winPos; im .h file!
        s = h + 184;
        resize( w, s);
    } else {
        extension->hide();
        resize( w, (h - 184) );
        if(pos() != winPos) move(winPos);
    }
}
Hab ich da ne falsche Reihenfolge? Muss ich im resizeEvent-Handler was machen?
Oder ist das ein Bug, äh Feature ... ?
Wer das bis hierher gelesen hat, vielen Dank dafür.
In den einschlägigen Foren hab ich das nicht gefunden. Bei Trolltech auch nicht. Und nicht in der Doku. Kann mir jemand mal helfen ?

opensuse 10.1; KDE 3.5.2; Qt 4.1.4; Brain 0.9.5738
#include <QSignatur>
kallitokaco
Beiträge: 11
Registriert: 5. Juli 2008 13:59

Beitrag von kallitokaco »

Ich hatte auch das Problem, dass das Fenster nicht mehr kleiner wird. Da es hier noch keine Antwort gibt, poste ich sie mal.Sorry, dass ich nen so alten Thread wiederbelebe. Sie klappt bei Qt 4.6.0. Hat mich ganz schön viel Zeit gekostet, dadrauf zu kommen.

Das Problem liegt wohl daran, dass die Größe des ausgeblendeten Widgets immernoch im Layout gespeichert ist. Wieso genau ist mir auch nicht klar. Bin mir nicht sicher, ob das die optimale Lösung ist, zumindest funktioniert sie.

Bsp.:

Code: Alles auswählen

...
if(extension->isVisible())
  {//verstecken
    extension->setMaximumSize(0,0); //Widget auf 0x0 verkleinern
    extension->resize(0,0); //ganz sicher gehen, das es auch 0x0 ist
    QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
//das resizevent() ausführen, somit ist die extension dann 0x0
    extension->setVisible(true); //das widget "anzeigen" bzw die größe im layout aktualisieren
    QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
//das ganze auch wirklich aktualisieren lassen
    resize(1,1); //das übergeordnete Fenster so klein machen wie möglich, damit auch der spalt verschwindet
    extension->setVisible(false);
//die extension zur vollständigkeit halber auch noch verstecken, sonst tut das anzeigen nicht mehr
  }
  else
  {//zeigen
    extension->setMaximumSize(QWIDGETSIZE_MAX,QWIDGETSIZE_MAX); 
//Die extension so groß werden lassen wie möglich
    extension->resize(320,200);
//die extension auf die defaultgröße vergrößern
    extension->setVisible(true);
//und wieder sichtbar machen
  }...
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Es gibt in den Examples unter "examples/dialogs/extension" auch ein Beispiel. Vllt. hilft das weiter.
Antworten