Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to do a "no break" QHBoxLayout
Qt 6.11 is out! See what's new in the release blog

How to do a "no break" QHBoxLayout

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 4 Posters 5.8k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • JonBJ Offline
    JonBJ Offline
    JonB
    wrote on last edited by JonB
    #1

    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  XXX
    

    I presume this is no problem, the containing QHBoxLayout will 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 XXX widgets I have a few different YYY widgets. 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  YYY
    

    The 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  YYY
    

    The 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  YYY
    

    Hence 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 own QHBoxLayout on the overall QHBoxLayout, but how will I indicate this sub-QHBoxLayout must 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 parent QHBoxLayout?

    1 Reply Last reply
    0
    • SGaistS SGaist

      Hi,

      I think you'll be interested in the Flow Layout Example for the layouting you seek.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #13

      @SGaist's suggestion of the Flow Layout Example is the way to go for anyone wanting this kind of flow layout in Qt.

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #2

        Hi,

        I think you'll be interested in the Flow Layout Example for the layouting you seek.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        JonBJ 2 Replies Last reply
        2
        • SGaistS SGaist

          Hi,

          I think you'll be interested in the Flow Layout Example for the layouting you seek.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #3

          @SGaist
          I have looked at that, and now looked at the QBoxLayoutmethods & 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 DIV element does:

          <div width="1000px">
          XXX  XXX  XXX  XXX  XXX  XXX  XXX  XXX  
          </div>
          

          would give

          XXX  XXX  XXX  XXX  XXX  XXX  XXX  XXX  
          

          but

          <div width="100px">
          XXX  XXX  XXX  XXX  XXX  XXX  XXX  XXX  
          </div>
          

          would give

          XXX  XXX  XXX
          XXX  XXX  XXX
          XXX  XXX  
          

          So it just flows elements as necessary. But the docs only shows a QHBoxLayout placing 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 QHBoxLayout allow stuff to flow below (like "word wrap") or not, please? If not, is there a different layout/widget which behaves like a simple DIV, I would have thought this was an extremely common requirement for layout?

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by SGaist
            #4

            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.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            JonBJ 2 Replies Last reply
            3
            • SGaistS SGaist

              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.

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #5

              @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.

              1 Reply Last reply
              0
              • SGaistS SGaist

                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.

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #6

                @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.cpp adds only widgets to the layout, via QLayout::addWidget(). As per https://doc.qt.io/qt-5/qlayout.html#addWidget, that in turn calls the FlowLayout::addItem(QLayoutItem *item) override, with a QWidgetItem for item, which adds it to its internal QList<QLayoutItem *> itemList used 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 add QHBoxLayouts) to the FlowLayout. The base QLayout does not have addLayout() in the way it has addWidget(). 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 in FlowLayout::itemList. I thought I also needed addChildLayout() to actually add the layout onto the FlowLayout, 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 QLayout rather than a QWidget onto the FlowLayout? Do I just need to call FlowLayout::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:

                jsulmJ 1 Reply Last reply
                0
                • Cobra91151C Offline
                  Cobra91151C Offline
                  Cobra91151
                  wrote on last edited by Cobra91151
                  #7

                  Hello!

                  How about using QGridLayout instead of QHBoxLayout, you can set the row, column and alignment of your widgets: https://doc.qt.io/qt-5/qgridlayout.html#addWidget-1

                  Also it should expand to your needs by setting setSizePolicy to your widgets: https://doc.qt.io/qt-5/qwidget.html#setSizePolicy-1

                  JonBJ 1 Reply Last reply
                  0
                  • Cobra91151C Cobra91151

                    Hello!

                    How about using QGridLayout instead of QHBoxLayout, you can set the row, column and alignment of your widgets: https://doc.qt.io/qt-5/qgridlayout.html#addWidget-1

                    Also it should expand to your needs by setting setSizePolicy to your widgets: https://doc.qt.io/qt-5/qwidget.html#setSizePolicy-1

                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by
                    #8

                    @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.

                    1 Reply Last reply
                    0
                    • JonBJ JonB

                      @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.cpp adds only widgets to the layout, via QLayout::addWidget(). As per https://doc.qt.io/qt-5/qlayout.html#addWidget, that in turn calls the FlowLayout::addItem(QLayoutItem *item) override, with a QWidgetItem for item, which adds it to its internal QList<QLayoutItem *> itemList used 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 add QHBoxLayouts) to the FlowLayout. The base QLayout does not have addLayout() in the way it has addWidget(). 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 in FlowLayout::itemList. I thought I also needed addChildLayout() to actually add the layout onto the FlowLayout, 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 QLayout rather than a QWidget onto the FlowLayout? Do I just need to call FlowLayout::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:

                      jsulmJ Offline
                      jsulmJ Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #9

                      @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?

                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                      JonBJ 1 Reply Last reply
                      0
                      • jsulmJ jsulm

                        @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?

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by
                        #10

                        @jsulm
                        Firstly, this new FlowLayout is to be a slot-in replacement for existing QHBoxLayouts which use addLayout() 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 from QLayout, has an addlayout(), but QLayout itself does not. There is QLayout::addItem(), which is what I am overriding/asking about. It takes a QLayoutItem, which includes a QLayout object, not just a QWidgetItem one, so I'm trying figure how to do that correctly.

                        If the answer is "I've looked at that Qt sample, and FlowLayout is 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?

                        1 Reply Last reply
                        0
                        • SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #11

                          Nothing wrong with adding a layout. See the implementation of QBoxLayout::insertLayout.

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          JonBJ 1 Reply Last reply
                          2
                          • SGaistS SGaist

                            Nothing wrong with adding a layout. See the implementation of QBoxLayout::insertLayout.

                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on last edited by
                            #12

                            @SGaist Will do next week, thanks.

                            1 Reply Last reply
                            0
                            • SGaistS SGaist

                              Hi,

                              I think you'll be interested in the Flow Layout Example for the layouting you seek.

                              JonBJ Offline
                              JonBJ Offline
                              JonB
                              wrote on last edited by JonB
                              #13

                              @SGaist's suggestion of the Flow Layout Example is the way to go for anyone wanting this kind of flow layout in Qt.

                              1 Reply Last reply
                              0

                              • Login

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved