Reputation: 784
I have annoying problem. I created QVBoxLayout on which I added my widgets. This is sample from my constructor:
layout = new QVBoxLayout;
layout->setMargin(0);
layout->setContentsMargins(QMargins(0,0,0,0));
layout->setSpacing(0);
And then I have function to add widgets.
layout->addWidget(_wave);
_wave is my own widget. But you can add whatever you want, for example QButton.
What do I want achieve? Similar like this but without any spaces beetween widgets added to layout. Just only QButtons or other widget, sticked each other.
I added everywhere setMargins, setSpacing etc. Please help me with that, I don't really have an idea what should I do.
Sorry for colors, but I wanted to mentioned what I want to achieve. I have mainWindow on which I added QWidget. This widget have blue background. Then to the layout, Im addding some widgets, which are orange on this image. I just want to be sure, that this blue background between widget isnt visible. I want to have widget under widget, without any space.
Upvotes: 11
Views: 22851
Reputation: 71
It seems like by default QT layouts do stretch their child widgets to fill the space of the layout. I found a way to achieve what I believe you are looking for. You can add a spacer to the layout with sizeType Expanding (default), and it will take up all the space in the layout and shrink the other widgets to their minimum size. You can do this in the visual designer of QT Creator or in code with something like this:
QVBoxLayout *layout = ui->verticalLayout_2;
layout->setContentsMargins(QMargins(0,0,0,0));
layout->setSpacing(0);
QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding);
layout->addSpacerItem(spacer);
for (int i=0; i<5; ++i)
{
auto button = new QPushButton(ui->centralwidget);
button->setText("Click me");
layout->insertWidget(layout->count() - 1, button, 0, Qt::AlignmentFlag::AlignTop);
}
If done in code you'll probably want to insert the widget at count() - 1, so the spacer is the last item in the layout.
Edit: kiss-o-matic's answer does actually the exact same thing in 1 line. And yeah it would probably be better to add the spacer after all other items unless, like me, you're doing it for a scroll area where items will be added by user input. That's why I added spacer first then items later.
Upvotes: 2
Reputation: 5978
As the Qt document says, some default GUI widget has extra frame around it.
Take QPushButton
as an example:
In some GUI styles a default button is drawn with an extra frame around it, up to 3 pixels or more. Qt automatically keeps this space free around auto-default buttons, i.e. auto-default buttons may have a slightly larger size hint.
So the culprit is not the layout but the widget itself instead. "Invisible" margin of a default widget remains even if the spacing of the layout has been set to 0.
If you really need a "compact" layout, my suggestion is to resort to the stylesheet of the widget.
Here are examples to illustrate the idea:
Here, we have a vertical layout with both margin and spacing equal to 0, and the buttons with custom stylesheet:
QPushButton {
border: 2px solid #8f8f91;
border-radius: 6px;
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #f6f7fa, stop: 1 #dadbde);
min-width: 80px;
}
// (further stylesheet for button click is needed)
Resetting stylesheet allows us to make the layout more compact:
Insert a default QPushButton
to see the difference:
You can see there is space around the default QPushButton
. That's the same for other kinds of widgets.
Upvotes: 2
Reputation: 1161
I know the question was posted a year ago, but if it can help some people save some time, I would be glad. I had the same problem and was able to solve it by setting:
QFrame.setFrameShape()
to NoFrame
QFrame.setLineWidth()
to 0.The image below is the result of 2 QtextEdit
put side by side in a Layout, using the described method.
http://doc.qt.io/qt-5/qframe.html#lineWidth-prop
Upvotes: 6
Reputation: 904
I could be wrong but there does not seem to be an obvious and non-hack of a way to do what you desire. However, according to the documentation you may find that just doing a manual layout will solve your problem. (http://doc.qt.io/qt-5/layout.html : Manual Layout)
It seems as if one could implement a Layout class that actually provides a very compact horizontal or vertical layout and I believe I had written one a few years ago using Python and Qt. With that in mind, you should be able to implement your own MyCompactLayout(horizontal=True)
and use it.
Upvotes: 1
Reputation: 1181
Try this to achieve a "tight" look. Note that if you resize the parent widget, they will not move. Not sure if this is what you want or not, but...
// After all widgets are added to the layout
layout->insertStretch( -1, 1 );
The 2nd argument needs to be higher than any other stretch factor. Stretch factor is default zero, so if you don't set it, the above one-liner should work.
Upvotes: 4