It's working well but it is possible to center items vertically?
You mean, if the window width is not an even multiple of the items' widths you want equal space on the left and right sides of each row of items? You would have to modify the code in the FlowLayout doLayout() method. The critical section is this bit of code:
int nextX = x + item->sizeHint().width() + spaceX;
if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
x = effectiveRect.x();
y = y + lineHeight + spaceY;
nextX = x + item->sizeHint().width() + spaceX;
lineHeight = 0;
}
if (!testOnly)
item
->setGeometry
(QRect(QPoint(x, y
), item
->sizeHint
()));
x = nextX;
lineHeight = qMax(lineHeight, item->sizeHint().height());
int nextX = x + item->sizeHint().width() + spaceX;
if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
x = effectiveRect.x();
y = y + lineHeight + spaceY;
nextX = x + item->sizeHint().width() + spaceX;
lineHeight = 0;
}
if (!testOnly)
item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
x = nextX;
lineHeight = qMax(lineHeight, item->sizeHint().height());
To copy to clipboard, switch view to plain text mode
The first if() clause is checking to see if there is enough space on the current line to fit the current item. If not, the contents of the clause are executed, which sets the x coordinate of the item to the left side of the layout rectangle (which has been adjusted for margins) and the y coordinate to the top of the next line. After this clause is complete, the geometry for the item is set to whatever has been calculated (eg. further along the current line or at the start of the next line).
The problem with this code is that each item gets laid out, one after the other, and once an item is positioned it is forgotten. What you will need to do instead is accumulate the items and their widths until the line is full, then calculate how much space remains in the width of the "effectiveRect" after subtracting the width of each item, and inter-item spacing. Divide that by two, add it to the x coordinates you've saved, then set the geometry for each item in the line. Clear the arrays of saved items, positions, and sizes and move to the next row.
Alternatively, you can make a two-pass algorithm. Let doLayout() do its thing. After the foreach() loop, make a second pass over the items. As long as the y-coordinate of the item's position is the same, accumulate the widths of the items. That's a row. At the end of the row, do the calculation to determine how much space is left over, and go back over those items to shift their x positions again. Then clear out the stuff you've saved and do the next row, etc. Be sure you don't forget the last row by exiting the loop too soon.
Bookmarks