[SOLVED] Resizing QVBoxLayout without changing content size but changing spacing
-
If you don't want the text boxes to resize then use setFixedSize() on them. Then you don't need any stretches.
-
The problem with that is, that the window should be resizable by the user. If that happens and the user enlarges the window, anything has to be stretched. Now, when I use fixed sizes for QTextEdits, they are fixed in the window on top and the only thing that stretches is the QLabel over the QPushButton. That is not really the effect I'd like to have. What would look much better is when the spacing between the QTextEdits would stretch, so every QTextEdit would move relative to the enlarging window.
Is there a hack to do that in a QGridLayout or do I have to manage this with nested QVBoxLayouts --> addStretch()? -
It does exactly what you want. There must be something else wrong with your layout. Can you show the code that creates it?
-
Sure:
@this->layout_g = new QGridLayout();this->layout_h = new QHBoxLayout(); this->label_columns = new QLabel("Persons:"); this->layout_h->addWidget(label_columns); this->button_add_person = new my_QPushButton("+"); this->layout_h->addWidget(button_add_person); this->button_add_person->setFocusPolicy(Qt::ClickFocus); this->button_add_person->setCursor(Qt::PointingHandCursor); connect(this->button_add_person, SIGNAL(clicked()), this, SLOT(addEdit())); this->button_remove_person = new my_QPushButton("-"); this->layout_h->addWidget(button_remove_person); this->button_remove_person->setFocusPolicy(Qt::ClickFocus); this->button_remove_person->setCursor(Qt::PointingHandCursor); connect(this->button_remove_person, SIGNAL(clicked()), this, SLOT(removeEdit())); this->layout_g->addLayout(layout_h, 0, 0, 1, 1); for(int i = 0; i < 11; i++) { this->list_edits.append(new QTextEdit()); this->layout_g->addWidget(list_edits.last(), i+1, 0, 1, 1); this->list_edits.last()->setMinimumWidth(150); this->list_edits.last()->setFixedHeight(26); } this->label_rows = new QLabel("Row Counter:"); this->layout_g->addWidget(label_rows, this->layout_g->rowCount(), 0, 1, 1); this->spinbox_rows = new QSpinBox(); this->layout_g->addWidget(spinbox_rows, this->layout_g->rowCount(), 0, 1, 1); this->spinbox_rows->setRange(1, 10000); this->spinbox_rows->setValue(100); this->button_create = new QPushButton("Create Table"); this->layout_g->addWidget(button_create, this->layout_g->rowCount(), 0, 1, 1); this->button_create->setDefault(true); this->button_create->setCursor(Qt::PointingHandCursor); connect(this->button_create, SIGNAL(clicked()), this->instance_parent, SLOT(applySettings())); this->checkbox_savesettings = new QCheckBox("Save Settings"); this->layout_g->addWidget(checkbox_savesettings, this->layout_g->rowCount(), 0, 1, 1); this->checkbox_savesettings->setChecked(true); this->setLayout(layout_g);@
After running this example, when I try to enlarge the window by pulling down the bottom border, only the second QLabel ("Row Counter:") stretches and fills the new gained place in the window, what looks really bad, because it centers the text and so the label moves up away from the QSpinBox... very bad..
Unfortunatelly, the block with the 10 QTextEdits is fixed with fixed spacing between them.
Btw.: The window is a QDialog, but I don't think that it matters... -
bq. only the second QLabel (“Row Counter:”) stretches and fills the new gained place in the window
That's because the label is the only element in that layout that doesn't have fixed height. If you give it one ( setFixedHeight(XX) ) then the layout won't have any element to stretch and will start to increase padding between elements.
Btw. You don't have to stick this-> in front of everythig, this is implicit in member functions. Also you don't need to keep a pointer to every element in your class eg. layouts tht you will never refer to later. You can make them local eg.
@
{
auto layout_g = new QGridLayout();
...
setLayout(layout_g); //no longer need layout_g variable, the thing it points to is managed by the parent now
}
@ -
So that means that setting an explicit size to a QWidget has a higher priority then stretching, but setting a stretchFactor '0' to every QWidget (as it is by default) has a lower priority and Qt picks out a victim that will although be stretched? According to which rules does Qt pick out the QWidget that will be stretched in case of no specific size settings and all QWidgets have the default strechFactor '0'? Does it take the first QWidget of the window or what is the algorithm then?
To my mind Qt should also stretch the spacings between the QWidgets in that case, as long as programmer doesn't pass a definite stretchFactor to a QWidget... -
It goes more or less like this (separately in vertical and horizontal):
- Add minimum sizes specified for all items in a layout, then add minimum spacing between them specified for the layout, then grow the window if it's too small to fit everything
- Subtract the sum of minimal spacing from the window size. That's the available space for layout items.
- Subtract from it the sum of all items that have fixed size. That's the space available for growing items.
- Split the available space between growing items using stretch factor. The name "stretch factor" is not very good. It really is share factor or available space fraction. For example if one item has stretch factor 3 and the other 5 then the first gets 3/8 of the space and the other 5/8. 0 acts more or less like 1. if all items have factor 0 the space gets thus distributed equally.
- Distribute any space left by adding equal fractions to the spacing between items. Notice that this step only takes place if there are no growing items in the layout. Otherwise they take all the space and there's nothing left to divide.
-
Ahh there we go, thank you! I'm again wondering from where did you get all that knowlege? I mean or I bet, that algorithms like this one are not written in any Qt documentation I can find in the internet, or do I only have the wrong websites?
Such interesting stuff!
-
Well it's not an official algorithm. It's just how I came to think about it and it works 90% of the time. It doesn't take into consideration all the settings like minimum and maximum sizes or size hints/policies. The official steps are explained "here":http://qt-project.org/doc/qt-5/layout.html#adding-widgets-to-a-layout but I find them a little confusing and not as easy to reason about in simple cases such as yours.
-
Look, I was wrong again, there is a description in the documentation :-P
Well, you're right it's a bit more confusing than yours, so thank's again.