QDockWidget with a QGridLayout - Widget within the Layout do not align to the top
-
25-04-2021 - |
Вопрос
I'm attempting to create a dockable toolbar (similar to what you use in Photoshop) that will hold a 2 x (n) grid of buttons. My idea is to use a QGridLayout parented to a blank QWidget, which is added to a QDockWidget, and add buttons to the QGridLayout. This seems to be working except for the aligning.
I've set the align for the buttons...
myLayout->addWidget(button1,0,0,1,1,Qt::AlignTop);
myLayout->addWidget(button2,0,1,1,1,Qt::AlignTop);
myLayout->addWidget(button3,1,0,1,1,Qt::AlignTop);
myLayout->addWidget(button4,1,1,1,1,Qt::AlignTop);
...however the grid is expanding to the full height of the QDockWidget, as seen below:
The buttons are also expanding horizontally as well, to fill the entire space. I figure I can just restrict the ability to re-size it horizontally (if this is possible?).
Is there a function I'm overlooking in the doc to control the GridLayout a little better to restrict it filling the entire width/height of the parent widget? And as a side-question, is there a way to prevent a QDOckWidget from being re-sized a certain direction?
Решение
Use a QVBoxLayout where you add first your QGridLayout and then add a stretch like this:
my_vboxlayout->addLayout( my_gridlayout );
my_vboxlayout->addStretch( 1 );
Alternatively you can tell your QGridLayout that the last row should expand to a maximum size, which will push up the buttons.
In your case it would be:
mygridlayout->setRowStretch( 2, 1 ); // give 3rd row maximum space
Links to documentation:
QBoxLayout
QGridLayout
Другие советы
From the documentation:
QGridLayout takes the space made available to it (by its parent layout or by the parentWidget()), divides it up into rows and columns, and puts each widget it manages into the correct cell.
Columns and rows behave identically; we will discuss columns, but there are equivalent functions for rows.
Each column has a minimum width and a stretch factor. The minimum width is the greatest of that set using setColumnMinimumWidth() and the minimum width of each widget in that column. The stretch factor is set using setColumnStretch() and determines how much of the available space the column will get over and above its necessary minimum.
So the easiest way would be to use a fixed size of the dockable widget QWidget::setFixedSize. In general, I would not recommend it (managing the layout ) but it is perfect for your case for the following reasons:
- All buttons have the same size, so you know roughly the size of the toolbar depending on the number of buttons.
- you don't need to manage the layout behavior.
- you can do it with either dimension, or both
For example, when adding a button
void addButton(QWidget* w,QGridLayout* wl, QButton* button, posParams...){
// w is the widget inside the QDockWidget (edit)
//wl is w layout
//break the constraints, the widget can be resized
w->setFixedSize(QSize(QWIDGETSIZE_MAX,QWIDGETSIZE_MAX));
// only line to change if you want to hide, remove widget
wl->addWidget(button, params);
//fit to contents
w->adjustSize();
// can be swapped to w->setFixedHeight, setFixedWidth
w->setFixedSize(w->size());
}
Try it and verify things don't get awry when you dock and undock the widget after modification. You should note that breaking the constraint also break the ones of the layout.
In general there is hierarchy between QLayout::SizeConstraint, QWidget::minimumSizeHint, QWidget::minimumSize, and you can find it in the documentation.
QWidget::minimumSize
is not set by default. When it is, it prevails overQWidget::minimumSizeHint
QWidget::minimumSizeHint
is invalid if the widget is not in a layout (meaning that it can be resized to 0 with the mouse), otherwise use the one defined by the layout.QLayout::SizeConstraint
holds the default layout behavior of the widgets it *directly * manage. If you nest a layoutA
within a layoutB
, all widgets added toA
will use its property. Also if a widgetW
inB
define its own layout, then this layout constraints are the one to be applied for the widgetW
.