Question

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:

Strange Layout

  • Which property causes this different behaviour between the two widgets, one beeing centered, the other being at a fixed position?
  • How can I influence the alignment (I can probably add a flexible spacer to fix it, but ideally I would like to avoid that)? I tried with Qt::AlignTop, but that made the blue widget disappear.
Was it helpful?

Solution 2

Although not a minimal solution you could probably fix the alignments by adding a QHBoxLayout in the cell for the green widget and a QVBoxLayout in the cell for the blue widget. Add the green widget to the QHBoxLayout and the blue widget to the QVBoxLayout. Then apply addStretch(n) to both the QHBoxLayout and QVBoxLayout. Maybe this is what you already mentioned you could do and then we are at the same level of knowledge concerning this. I believe this is the way I have solved these kind of issues and I haven't spent more time on it.

OTHER TIPS

Althought this question is pretty old, I will add my answer for all those that come here afterwards, like me.

Setting the alignment either with
layout->setAlignment(leftHeader, Qt::AlignHCenter | Qt::AlignTop);
or with
layout->addWidget(leftHeader, 1, 0, Qt::AlignTop);
is intuitiv and seems to be the right way. If it is setup completly 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:

  1. Outside of the layout leftHeader got a fixed width of 20 - ok, but no given height.
    With the defaults of QWidget this leads to a default-height of 0.
  2. Documentation of 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.

Try this:

setAlignment(Qt::AlignHCenter | Qt::AlignTop );
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top