PDA

View Full Version : Shrink QMainWindow to Minimum Size



kloffy
17th February 2008, 00:29
My Google searches were not encouraging but I'll still give it a try here:
Is there an easy way to shrink a QMainWindow to its minimum size? The problem I have is the following. In my application I have a QDockWidget that is hidden by default. When the user toggles the visibility of the QDockWidget on, the QMainWindow expands to accommodate the dock. However, once the user closes or floats the dock I would like QMainWindow to return to its original size.

fanat9
17th February 2008, 02:00
Just set right size policy and call adjustSize() for your mainwindow on dock hiding event.

So, in main window constructor: this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
On dock hiding event adjustSize() for your qmainwindow.

kloffy
17th February 2008, 02:20
That's pretty close, but not quite. Now the window changes its size 3 times. At the beginning it is nice and small, the way I want it to be. Then when I toggle the dock, it roughly doubles its size in addition to adding space to the dock. Then I toggle the dock off, the additional space for the dock dissappears, but the window stays roughly twice as big as it was on startup.

Edit: Here's the relevant code:

ApplicationWindow::ApplicationWindow() : QMainWindow(NULL, Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint | Qt::WindowSystemMenuHint)
{
setWindowTitle(tr("QTApp"));
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);

buttonStart = new QPushButton(tr("Start"));
buttonStart->setDefault(true);

connect(buttonStart, SIGNAL(clicked()), this, SLOT(start()));

center = new QWidget(this);
center->setMinimumSize(400, 150);

QGroupBox *groupBoxOptions = new QGroupBox(tr("Options"));
QGridLayout *layoutOptions = new QGridLayout;

exepathEdit = new QLineEdit(groupBoxOptions);
cmdlineEdit = new QLineEdit(groupBoxOptions);

layoutOptions->addWidget(new QLabel(tr("Exepath:")), 1, 1);
layoutOptions->addWidget(exepathEdit, 1, 2);

layoutOptions->addWidget(new QLabel(tr("Cmdline:")), 2, 1);
layoutOptions->addWidget(cmdlineEdit, 2, 2);

layoutOptions->setColumnStretch(1, 20);
layoutOptions->setColumnStretch(2, 80);

groupBoxOptions->setLayout(layoutOptions);

textEdit = new QTextEdit(this);
textEdit->setReadOnly(true);

QDockWidget *dock = new QDockWidget(tr("Output"), this);
dock->setAllowedAreas(Qt::BottomDockWidgetArea);
dock->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable);
dock->setWidget(textEdit);

addDockWidget(Qt::BottomDockWidgetArea, dock);
viewMenu->addAction(dock->toggleViewAction());

dock->hide();

connect(dock, SIGNAL(visibilityChanged(bool)), this, SLOT(adjust()));

QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addStretch(1);
buttonLayout->addWidget(buttonStart);
buttonLayout->addStretch(1);

QVBoxLayout *centerLayout = new QVBoxLayout;
centerLayout->addWidget(groupBoxOptions);
centerLayout->addLayout(buttonLayout);
center->setLayout(centerLayout);

setCentralWidget(center);
}

void ApplicationWindow::adjust()
{
adjustSize();
}

Edit: In addition to that I also tried overriding sizeHint instead of specifing the minimum size on the center widget. That resulted in the old behavior. (Window expands on dock toggle, stays big)

fanat9
17th February 2008, 03:11
Well, again you have to set correct size/size policy for all widgets. Check sizeHint's for your widgets before and after resizing - it will tell you a lot =)
...override sizeHint ? Try to set maximum, not minimum size =)

kloffy
17th February 2008, 17:54
After trying out various combinations I came up with this:


ApplicationWindow::ApplicationWindow(QWidget* parent) : QMainWindow(parent, Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint | Qt::WindowSystemMenuHint)
{
setWindowTitle(tr("QTApp"));
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
setMinimumSize(400, 150);

createActions();
createMenus();

center = new QWidget(this);
center->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);

QStringList types;
types << "Executable Files (*.exe)" << "Any files (*)";

fileDialog = new QFileDialog(this);
fileDialog->setWindowTitle(tr("Select a program"));
fileDialog->setAcceptMode(QFileDialog::AcceptOpen);
fileDialog->setFilters(types);

QGroupBox *groupBoxOptions = new QGroupBox(tr("Options"), center);
QGridLayout *layoutOptions = new QGridLayout(groupBoxOptions);

exepathEdit = new QLineEdit(groupBoxOptions);
cmdlineEdit = new QLineEdit(groupBoxOptions);

buttonSelectFile = new QPushButton(tr("Select..."), groupBoxOptions);

connect(buttonSelectFile, SIGNAL(clicked()), this, SLOT(selectFile()));

layoutOptions->addWidget(new QLabel(tr("Exepath:")), 1, 1);
layoutOptions->addWidget(exepathEdit, 1, 2);
layoutOptions->addWidget(buttonSelectFile, 1, 3);

layoutOptions->addWidget(new QLabel(tr("Cmdline:")), 2, 1);
layoutOptions->addWidget(cmdlineEdit, 2, 2, 1, 2);

layoutOptions->setColumnStretch(1, 20);
layoutOptions->setColumnStretch(2, 60);
layoutOptions->setColumnStretch(3, 20);

groupBoxOptions->setLayout(layoutOptions);

dock = new QDockWidget(tr("Output"), this);
dock->setAllowedAreas(Qt::BottomDockWidgetArea);
dock->setFeatures(QDockWidget::DockWidgetClosable);

textEdit = new QTextEdit(dock);
textEdit->setReadOnly(true);
textEdit->setFixedHeight(100);

dock->setWidget(textEdit);

addDockWidget(Qt::BottomDockWidgetArea, dock);

viewMenu->addAction(dock->toggleViewAction());

connect(dock, SIGNAL(visibilityChanged(bool)), this, SLOT(adjust()));

buttonStart = new QPushButton(tr("Start"));
buttonStart->setDefault(true);

connect(buttonStart, SIGNAL(clicked()), this, SLOT(start()));

QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addStretch(1);
buttonLayout->addWidget(buttonStart);
buttonLayout->addStretch(1);

QVBoxLayout *centerLayout = new QVBoxLayout;
centerLayout->addWidget(groupBoxOptions);
centerLayout->addLayout(buttonLayout);
center->setLayout(centerLayout);

setCentralWidget(center);
}

void ApplicationWindow::adjust()
{
adjustSize();
}

There is something about having a minimumSize on the QMainWindow and a fixedHeight on the dock widget that makes it work. It's not a nice solution - I had to sacrifice floating and the dock widget cannot be resized - but it'll do for now. I would still love to find a propper way of doing this. Here's a quick and dirty ASCII art:


Without Dock:
____________________
|Main |
|--------------------|
| .-Options---------.|
| | Exe: [Blablub ] ||
| | Cmd: [Blablub ] ||
| |_________________||
| [Start] |
|____________________|

With dock:
____________________
|Main |
|--------------------|
| .-Options---------.|
| | Exe: [Blablub ] ||
| | Cmd: [Blablub ] ||
| |_________________||
| [Start] |
|--------------------|
|Output x|
| .-----------------.|
| |Blablub... ||
| |Blablub... ||
| | ||
| |_________________||
|____________________|
It doesn't have to be a dock, if anyone knows a custom widget that allows you to do something like this, I would appreciate if you point me to it.