The following code (Qt 5, same behaviour with Qt 4.8) uses a QGridLayout
to add widgets above and to the left of a QScrollArea
(to serve as a kind of header later):
#include <QApplication>
#include <QMainWindow>
#include <QGridLayout>
#include <QScrollArea>
class ColoredWidget : public QWidget {
public:
ColoredWidget(const QColor& color, QWidget* parent) : QWidget(parent) {
QPalette pal;
QBrush brush(color);
brush.setStyle(Qt::SolidPattern);
pal.setBrush(QPalette::Active, QPalette::Window, brush);
setPalette(pal);
setAutoFillBackground(true);
}
};
class MainWindow : public QMainWindow {
public:
MainWindow(QWidget* parent) : QMainWindow(parent) {
resize(300, 400);
QWidget* centralwidget = new ColoredWidget(QColor(0xff, 0xf0, 0xb5), this);
QGridLayout* layout = new QGridLayout();
centralwidget->setLayout(layout);
setCentralWidget(centralwidget);
// create widget with fixed height of 20 px and maximum width of 200
QWidget* topHeader = new ColoredWidget(Qt::green, centralwidget);
topHeader->setMaximumWidth(200);
topHeader->setFixedHeight(20);
// create widget with fixed width of 20 px and maximum height of 200
QWidget* leftHeader = new ColoredWidget(Qt::blue, centralwidget);
leftHeader->setFixedWidth(20);
leftHeader->setMaximumHeight(200);
// create scroll area as main widget
QWidget* view = new QScrollArea();
layout->addWidget(topHeader, 0, 1);
layout->addWidget(leftHeader, 1, 0);
// layout->addWidget(leftHeader, 1, 0, Qt::AlignTop); // widget not displayed at all!
layout->addWidget(view, 1, 1);
}
};
int main(int argc, char ** argv) {
QApplication app( argc, argv );
MainWindow win(0);
win.show();
return app.exec();
}
The QGridLayout
documentation says that "Columns and rows behave identically", thus I would expect that the two widgets are layouted the same way.
However, the left one is automatically vertically centered, while the top widget is aligned to the left within the cell (and not centered horizontally). I would like to have the left widget also at a fixed position, means aligned to the top:
Qt::AlignTop
, but that made the blue widget disappear.Setting the alignment either with:
layout->setAlignment(leftHeader, Qt::AlignHCenter | Qt::AlignTop);
or with:
layout->addWidget(leftHeader, 1, 0, Qt::AlignTop);
is intuitive and seems to be the right way. If it is setup completely it is also working as expected.
But why does the Widget vanish then?
Long story short: because leftHeader has a size of 0.
In my pretty similar situation I've setfixedHeight()
and the widget reappeared, this should also work by setting a value for minimalHeight()
for example.
Long Story - Details
I've put myself in position of gridLayout and tried to determine the size of leftHeader
:
leftHeader
got a fixed width of 20 - ok, but no given height.void QGridLayout::addWidget()
and void QGridLayout::addLayout()
states:...
The alignment is specified by alignment. The default alignment is 0, which means that the widget fills the entire cell.
...
source
Hence for default alignment of 0 the height of leftHeader
is obviously set as height of its row.
But in case a different Qt::Alignment
is used, as in the question (Qt::AlignTop
), it is not that simple.
From my point of view the layout is unable to determine the correct height without further settings from the designer.
Having a quick look at the implementation of void QGridLayout::addWidget()
, we can detect that a QLayoutItem
(as part of QGridBox
) is created inside the QGridLayout
for each added widget resp. Layout.
So it seems that the QGridLayout
relies on default layout mechanisms of Qt based on the settings from the added widget/Layout (like minSize
, maxSize
, BaseSize
, Size Increment
, etc ).
In combination with 1.) this implies a height of 0 for leftHeader
and therefore nothing to draw resp. it seems that the widget has vanished.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With