Expanding dialog

From QtCentreWiki

Jump to:navigation, search

How to make a dialog that adapts to its contents?

The Idea

Sometimes it is required to have a dialog which will change its size depending on what it is currently displaying. A typical example is a dialog having a toggle button called "More" that shows or hides some widget hierarchy which is considered optional for the dialog.

The Problem

The solution seems simple -- create a dialog in Designer, make a toggle button and connect its toggled(bool) signal to setShown(bool) slot of the widget that is to be shown or hidden, put it all into a layout and set the vertical size policy to "Fixed".

The problem is that size policies only apply to widgets that are inside layouts, not to top level widgets (and the dialog is a top level widget), so this won't be enough.

The Solution

Fortunately there is a solution. In Qt3 we had a setResizeMode() method which could be used to ask the dialog to be of fixed size. The method was removed from Qt4 API, but fortunately we received something in return -- QLayout has a sizeConstraint property which can be used to put a constraint on the widget owning the layout (which means our dialog).

 #include <QDialog>
 #include <QGroupBox>
 #include <QCheckBox>
 #include <QLineEdit>
 #include <QPushButton>
 #include <QGridLayout>
 
 class ExpandingDialog : public QDialog {
 public:
   ExpandingDialog(QWidget *parent = 0) : QDialog(parent){
     QGridLayout *l = new QGridLayout(this);
     l->addWidget(new QLineEdit, 0, 0);
     l->addWidget(new QPushButton("Find"), 0, 1);
 
     // create a toggle button
     QPushButton *moreButton = new QPushButton("More");
     moreButton->setCheckable(true);
     l->addWidget(moreButton, 1, 1);
 
     QGroupBox *expandBox = new QGroupBox;
     l->addWidget(expandBox, 2, 0);
 
     // set layout for the group box and add items
     QVBoxLayout *gboxlayout = new QVBoxLayout(expandBox);
     for(int i=0;i<5;i++){
       gboxlayout->addWidget(new QCheckBox(QString::number(i)));
     }
     // connect the button and the groupbox
     connect(moreButton, SIGNAL(toggled(bool)), expandBox, SLOT(setShown(bool)));
     // hide the optional box
     expandBox->hide();
 
     // make the dialog adjust to its layout
     layout()->setSizeConstraint(QLayout::SetFixedSize); // <- this does the trick!
   }
 };

Just for completeness, the main() function:

 #include <QApplication>
 
 int main(int argc, char **argv){
   QApplication app(argc, argv);
   ExpandingDialog dlg;
   dlg.show();
   return app.exec();
 }


Wysota 19:51, 25 January 2007 (CET)