How to do a "no break" QHBoxLayout
-
I have an up-coming requirement which I haven't had a chance to play with yet but anticipate an issue I'd like to clarify in advance.
There are to be a whole load of widgets in horizontal flow which must "wrap" (not scroll right) to the next line down when they reach the window width, which will vary on different devices. I do not want to force where the move-down occurs, it should only do it when it reaches the width:
XXX XXX XXX XXX XXX XXX XXX XXX XXX XXXI presume this is no problem, the containing
QHBoxLayoutwill expand vertically to wrap at the right point (correct?).(Having said that: which "expanding flag" will it need to ensure it wraps when it reaches a width rather than keep on going right, given that I don't have an explicit maximum width? Will I have to look at the desktop width and apply that value as a maximum?)
Now, my real question is: at the end of the the
XXXwidgets I have a few differentYYYwidgets. I want those horizontal, after a gap, but I do not want these to ever be broken onto a line below such that they get split:XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX YYY YYY YYYThe above is good, because the
YYYs are all together horizontally.XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX YYY YYY YYYThe above is bad, because the
YYYs are split. It would need to be:XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX YYY YYY YYYHence it's like a "no-break"/"keep-together" in a word processor or whatever on the
YYYs.How will I achieve that? I imagine I'll want the
YYYs in their ownQHBoxLayouton the overallQHBoxLayout, but how will I indicate this sub-QHBoxLayoutmust not be split/broken and must wrap to the next line as a whole if there is not enough horizontal room for it on its parentQHBoxLayout? -
Hi,
I think you'll be interested in the Flow Layout Example for the layouting you seek.
-
Hi,
I think you'll be interested in the Flow Layout Example for the layouting you seek.
-
Hi,
I think you'll be interested in the Flow Layout Example for the layouting you seek.
@SGaist
I have looked at that, and now looked at theQBoxLayoutmethods & docs. Now I don't know whether it implements what I assumed & need:Docs:
QBoxLayout takes the space it gets (from its parent layout or from the parentWidget()), divides it up into a row of boxes, and makes each managed widget fill one box.
Your example:
The position of each item in the layout is then calculated by adding the items width and the line height to the initial x and y coordinates. This in turn lets us find out whether the next item will fit on the current line or if it must be moved down to the next.
I assumed it handled a horizontal flow where the items exceeded its width and it could auto-wrap to the "next line" down if they exceeded. Like an HTML
DIVelement does:<div width="1000px"> XXX XXX XXX XXX XXX XXX XXX XXX </div>would give
XXX XXX XXX XXX XXX XXX XXX XXXbut
<div width="100px"> XXX XXX XXX XXX XXX XXX XXX XXX </div>would give
XXX XXX XXX XXX XXX XXX XXX XXXSo it just flows elements as necessary. But the docs only shows a
QHBoxLayoutplacing all its contents on one "line". I don't expect to have to use a grid and calculate it myself.That is the first part of my question. Does a
QHBoxLayoutallow stuff to flow below (like "word wrap") or not, please? If not, is there a different layout/widget which behaves like a simpleDIV, I would have thought this was an extremely common requirement for layout? -
No it's not. The desktop application world and the web world are radically different. Qt widgets predates the single page web concept.
As for QHBoxLayout, no, it won't automatically do wrapping as its goal is to handle horizontality hence my example suggestion.
-
No it's not. The desktop application world and the web world are radically different. Qt widgets predates the single page web concept.
As for QHBoxLayout, no, it won't automatically do wrapping as its goal is to handle horizontality hence my example suggestion.
@SGaist
Got it! Then I was certainly labouring under a misapprehension. I do understand about desktop vs web, though by Qt standards I am "surprised" there isn't a wrap-flow-layout. I now understand why you referred to me to example which has to calculate. I'll do a little Googling to see if others have asked about this, and refer to your sample code when I discover I have no alternative than to do it manually :) ... That didn't take long, same kind of questions on SO point to same flow layout example! Thanks for enlightening me. -
No it's not. The desktop application world and the web world are radically different. Qt widgets predates the single page web concept.
As for QHBoxLayout, no, it won't automatically do wrapping as its goal is to handle horizontality hence my example suggestion.
@SGaist , or @ whoever
I need some help, please, with making the supplied Qt Flow Layout Example work correctly which I have been referred to, and so have re-opened this thread.I have translated it to Python/PyQt successfully, that is not the issue.
The supplied example
main.cppadds only widgets to the layout, viaQLayout::addWidget(). As per https://doc.qt.io/qt-5/qlayout.html#addWidget, that in turn calls theFlowLayout::addItem(QLayoutItem *item)override, with aQWidgetItemforitem, which adds it to its internalQList<QLayoutItem *> itemListused in calculating. All this works fine.I need to add little layouts (as it happens,
QVBoxLayout, though I'd like it to work if I ever addQHBoxLayouts) to theFlowLayout. The baseQLayoutdoes not haveaddLayout()in the way it hasaddWidget(). Purely at a guess, I have made my code go:layout = QVBoxLayout() ... flowLayout.addChildLayout(layout) flowLayout.addItem(layout)This seems to work. I seem to need the
addItem()to put it inFlowLayout::itemList. I thought I also neededaddChildLayout()to actually add the layout onto theFlowLayout, but I can get rid of that line and it still seems to work/look the same.So... what is the correct/required way to add a
QLayoutrather than aQWidgetonto theFlowLayout? Do I just need to callFlowLayout::addItem()and that's it? I don't really get how that is working:void FlowLayout::addItem(QLayoutItem *item) { itemList.append(item); }Since all that does it appends to its internal list for calculating, I don't see how that is actually adding my sub-layout onto the
FlowLayout...?Yours, :confused:
-
Hello!
How about using
QGridLayoutinstead ofQHBoxLayout, you can set therow,columnandalignmentof yourwidgets: https://doc.qt.io/qt-5/qgridlayout.html#addWidget-1Also it should expand to your needs by setting
setSizePolicyto yourwidgets: https://doc.qt.io/qt-5/qwidget.html#setSizePolicy-1 -
Hello!
How about using
QGridLayoutinstead ofQHBoxLayout, you can set therow,columnandalignmentof yourwidgets: https://doc.qt.io/qt-5/qgridlayout.html#addWidget-1Also it should expand to your needs by setting
setSizePolicyto yourwidgets: https://doc.qt.io/qt-5/qwidget.html#setSizePolicy-1@Cobra91151
A grid layout doesn't do what a flow layout does. It won't flow things from line to line which is the whole point. -
@SGaist , or @ whoever
I need some help, please, with making the supplied Qt Flow Layout Example work correctly which I have been referred to, and so have re-opened this thread.I have translated it to Python/PyQt successfully, that is not the issue.
The supplied example
main.cppadds only widgets to the layout, viaQLayout::addWidget(). As per https://doc.qt.io/qt-5/qlayout.html#addWidget, that in turn calls theFlowLayout::addItem(QLayoutItem *item)override, with aQWidgetItemforitem, which adds it to its internalQList<QLayoutItem *> itemListused in calculating. All this works fine.I need to add little layouts (as it happens,
QVBoxLayout, though I'd like it to work if I ever addQHBoxLayouts) to theFlowLayout. The baseQLayoutdoes not haveaddLayout()in the way it hasaddWidget(). Purely at a guess, I have made my code go:layout = QVBoxLayout() ... flowLayout.addChildLayout(layout) flowLayout.addItem(layout)This seems to work. I seem to need the
addItem()to put it inFlowLayout::itemList. I thought I also neededaddChildLayout()to actually add the layout onto theFlowLayout, but I can get rid of that line and it still seems to work/look the same.So... what is the correct/required way to add a
QLayoutrather than aQWidgetonto theFlowLayout? Do I just need to callFlowLayout::addItem()and that's it? I don't really get how that is working:void FlowLayout::addItem(QLayoutItem *item) { itemList.append(item); }Since all that does it appends to its internal list for calculating, I don't see how that is actually adding my sub-layout onto the
FlowLayout...?Yours, :confused:
@JonB said in How to do a "no break" QHBoxLayout:
what is the correct/required way to add a QLayout rather than a QWidget onto the FlowLayout
Can't you add a widget which in turn has a layout in it?
-
@JonB said in How to do a "no break" QHBoxLayout:
what is the correct/required way to add a QLayout rather than a QWidget onto the FlowLayout
Can't you add a widget which in turn has a layout in it?
@jsulm
Firstly, this newFlowLayoutis to be a slot-in replacement for existingQHBoxLayouts which useaddLayout()in generic functions to add stuff onto them. Doing it by adding in a new widget may be an issue.Secondly, https://doc.qt.io/qt-5/layout.html states:
You can nest layouts using
addLayout()on a layout; the inner layout then becomes a child of the layout it is inserted into.QBoxLayout, which derives fromQLayout, has anaddlayout(), butQLayoutitself does not. There isQLayout::addItem(), which is what I am overriding/asking about. It takes aQLayoutItem, which includes aQLayoutobject, not just aQWidgetItemone, so I'm trying figure how to do that correctly.If the answer is "I've looked at that Qt sample, and
FlowLayoutis only to be used to add widgets, not layouts", I will respect that. But since adding a sub-layout seems to be working, though I don't get how, I thought it would be easiest if I pursued that direction? -
Nothing wrong with adding a layout. See the implementation of QBoxLayout::insertLayout.
-
Nothing wrong with adding a layout. See the implementation of QBoxLayout::insertLayout.
-
Hi,
I think you'll be interested in the Flow Layout Example for the layouting you seek.