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. Laying out items/widgets without stretching/spacing
Forum Updated to NodeBB v4.3 + New Features

Laying out items/widgets without stretching/spacing

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 4 Posters 194 Views 3 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 JonB

    After all these years of using Qt I still find getting what I want in layouts a "dark art". Yes, I have read the docs many times but seeming without clarity/true understanding :) So I thought I would ask about one simple case which I find myself wanting often. [This post inspired by thinking about https://forum.qt.io/post/832780 but not directly related to the issue there.]

    I would like, as an example:

    • A horizontal layout inside some parent widget.
    • I will want to place some widgets (e.g. QPushButtons and QLabels) on it.
    • I want all items laid out left to right, taking up their "natural" width, with no stretching/spacing before/between/after them. So the line of them will take up no more width than they need, they will be "packed" from left to right and there will be a gap/nothing to the right of them.

    When I Google for examples of this, or ask an AI, I see either (a) add a spacer as an extra, final item on the layout or (b) add a stretch on the final widget.

    And this "works" but for me it is not "right". For one thing it requires code which, say, wants to add a new final widget to "know" about the layout and code accordingly: in case (a) it must know not to append the new widget but rather insert it one before the the final spacer while in case (b) the stretch on the current final item must be removed and added to the newly added final item.

    What I want or expect is there should be an attribute/property specified once on the whole layout (not on any widget(s)) to say "this runs left to right with no spacing or right-justification", no matter what/when you might add any widgets.

    Is there such a simple property available on a layout? Have I missed something really easy which does this?

    P.S.
    In case anyone says: I have used the Qt "flow layout" example code when I have genuinely wanted multiline flow layout. And that effectively does make each line as I want. But the code for that is way too big/complex for just a single line/horizontal layout where I want widgets laid out left to right with no spacing.

    S Offline
    S Offline
    SimonSchroeder
    wrote last edited by
    #2

    @JonB said in Laying out items/widgets without stretching/spacing:

    Is there such a simple property available on a layout? Have I missed something really easy which does this?

    I don't think there is something like this. Adding a spacer to the right is how it is normally done. You could derive from QHBoxLayout and automatically add the spacer to the right/insert widgets before the space by just overloading addWidget().

    JonBJ 1 Reply Last reply
    1
    • S SimonSchroeder

      @JonB said in Laying out items/widgets without stretching/spacing:

      Is there such a simple property available on a layout? Have I missed something really easy which does this?

      I don't think there is something like this. Adding a spacer to the right is how it is normally done. You could derive from QHBoxLayout and automatically add the spacer to the right/insert widgets before the space by just overloading addWidget().

      JonBJ Online
      JonBJ Online
      JonB
      wrote last edited by
      #3

      @SimonSchroeder
      Thank you, for what appears to be confirmation of my understanding. I just don't get it.

      A horizontal layout (and of course all this applies to vertical layouts too, and perhaps other layouts) starts life as a container which apparently chooses to spread its content evenly across its width (right?). Then it seems "obvious" and "natural" to me that should be some "attribute" on the layout which one could alter to, say, "lay out from left with no extra spacing" and "lay out from right with no extra spacing", corresponding to "left align" and "right align", and perhaps another one of "center in layout, with no extra spacing" for "center align".

      I have used other UI toolkit designers and they worked like that, e.g. I'm pretty sure when I did Windows/Visual Studio it offered this basic functionality without having to do "stretch" or "spacer". This seems so basically obvious to me as a facility one would offer.

      Ah well. I shall do a bit more Googling and then presumably close this thread, with regret.

      1 Reply Last reply
      0
      • JonBJ JonB

        After all these years of using Qt I still find getting what I want in layouts a "dark art". Yes, I have read the docs many times but seeming without clarity/true understanding :) So I thought I would ask about one simple case which I find myself wanting often. [This post inspired by thinking about https://forum.qt.io/post/832780 but not directly related to the issue there.]

        I would like, as an example:

        • A horizontal layout inside some parent widget.
        • I will want to place some widgets (e.g. QPushButtons and QLabels) on it.
        • I want all items laid out left to right, taking up their "natural" width, with no stretching/spacing before/between/after them. So the line of them will take up no more width than they need, they will be "packed" from left to right and there will be a gap/nothing to the right of them.

        When I Google for examples of this, or ask an AI, I see either (a) add a spacer as an extra, final item on the layout or (b) add a stretch on the final widget.

        And this "works" but for me it is not "right". For one thing it requires code which, say, wants to add a new final widget to "know" about the layout and code accordingly: in case (a) it must know not to append the new widget but rather insert it one before the the final spacer while in case (b) the stretch on the current final item must be removed and added to the newly added final item.

        What I want or expect is there should be an attribute/property specified once on the whole layout (not on any widget(s)) to say "this runs left to right with no spacing or right-justification", no matter what/when you might add any widgets.

        Is there such a simple property available on a layout? Have I missed something really easy which does this?

        P.S.
        In case anyone says: I have used the Qt "flow layout" example code when I have genuinely wanted multiline flow layout. And that effectively does make each line as I want. But the code for that is way too big/complex for just a single line/horizontal layout where I want widgets laid out left to right with no spacing.

        J.HilkJ Offline
        J.HilkJ Offline
        J.Hilk
        Moderators
        wrote last edited by J.Hilk
        #4

        @JonB have you heard of the Flow Layout example?

        https://doc.qt.io/qt-6/qtwidgets-layouts-flowlayout-example.html

        I think it does exactly what you're looking for


        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


        Q: What's that?
        A: It's blue light.
        Q: What does it do?
        A: It turns blue.

        JonBJ 1 Reply Last reply
        0
        • J.HilkJ J.Hilk

          @JonB have you heard of the Flow Layout example?

          https://doc.qt.io/qt-6/qtwidgets-layouts-flowlayout-example.html

          I think it does exactly what you're looking for

          JonBJ Online
          JonBJ Online
          JonB
          wrote last edited by
          #5

          @J.Hilk
          If you read my question I carefully put in:

          P.S.

          In case anyone says: I have used the Qt "flow layout" example code when I have genuinely wanted multiline flow layout. And that effectively does make each line as I want. But the code for that is way too big/complex for just a single line/horizontal layout where I want widgets laid out left to right with no spacing.

          :)

          Yes, I have used flow layout where i wanted multiline flow layout. I even (had to) fix at least one "bug" in it. So I know it well. And as I said it is a lot of code, and (as I recall) uses absolute positioning to achieve it (that may not be correct, but it has to do a lot of measuring in order to calculate what should be pushed to the next line at least). Qt layout must already be doing a lot of work to achieve the "spread evenly across", I simply want it to offer not to do that and just lay out in the simplest way from left to right, and perhaps from right to left too.

          For the record, these layout features are certainly available in a very simple and default fashion from Visual Studio. No need for "spacers" or "stretchers".

          J.HilkJ 1 Reply Last reply
          0
          • JonBJ JonB

            @J.Hilk
            If you read my question I carefully put in:

            P.S.

            In case anyone says: I have used the Qt "flow layout" example code when I have genuinely wanted multiline flow layout. And that effectively does make each line as I want. But the code for that is way too big/complex for just a single line/horizontal layout where I want widgets laid out left to right with no spacing.

            :)

            Yes, I have used flow layout where i wanted multiline flow layout. I even (had to) fix at least one "bug" in it. So I know it well. And as I said it is a lot of code, and (as I recall) uses absolute positioning to achieve it (that may not be correct, but it has to do a lot of measuring in order to calculate what should be pushed to the next line at least). Qt layout must already be doing a lot of work to achieve the "spread evenly across", I simply want it to offer not to do that and just lay out in the simplest way from left to right, and perhaps from right to left too.

            For the record, these layout features are certainly available in a very simple and default fashion from Visual Studio. No need for "spacers" or "stretchers".

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote last edited by
            #6

            @JonB may bad

            I think if you provide max or fixed sizes, normal layouts work that way?

            I'm not entirely sure, been ages since I last used QWidgets


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            JonBJ 1 Reply Last reply
            0
            • J.HilkJ J.Hilk

              @JonB may bad

              I think if you provide max or fixed sizes, normal layouts work that way?

              I'm not entirely sure, been ages since I last used QWidgets

              JonBJ Online
              JonBJ Online
              JonB
              wrote last edited by JonB
              #7

              @J.Hilk said in Laying out items/widgets without stretching/spacing:

              I think if you provide max or fixed sizes, normal layouts work that way?

              I don't think so (but I will play with it again shortly). Not that I should have to or want either max or fixed sizes on widgets. When you do nothing special on the widgets a horizontal layout spreads them evenly across with "gaps" between each to achieve full justification from left to right, without changing the width of each one. I just want it not to do the "spread out" work and just place them left to right with no extra work. Simplez ;-)

              1 Reply Last reply
              0
              • S Offline
                S Offline
                SimonSchroeder
                wrote last edited by
                #8

                Most of the time I am just using a grid layout. This will help align widgets over multiple rows. The remaining cases where I do use QHBoxLayout I really want to spread it over the full width (or in the opposite direction: I want the dialog as narrow as possible so that there is no space for a spacer left). This leaves very few cases for spacer items in my layouts. Sometimes there is also some input element that can profit from more space and I'll make that one stretch (and thus don't need no additional spacer).

                1 Reply Last reply
                0
                • JonBJ JonB

                  After all these years of using Qt I still find getting what I want in layouts a "dark art". Yes, I have read the docs many times but seeming without clarity/true understanding :) So I thought I would ask about one simple case which I find myself wanting often. [This post inspired by thinking about https://forum.qt.io/post/832780 but not directly related to the issue there.]

                  I would like, as an example:

                  • A horizontal layout inside some parent widget.
                  • I will want to place some widgets (e.g. QPushButtons and QLabels) on it.
                  • I want all items laid out left to right, taking up their "natural" width, with no stretching/spacing before/between/after them. So the line of them will take up no more width than they need, they will be "packed" from left to right and there will be a gap/nothing to the right of them.

                  When I Google for examples of this, or ask an AI, I see either (a) add a spacer as an extra, final item on the layout or (b) add a stretch on the final widget.

                  And this "works" but for me it is not "right". For one thing it requires code which, say, wants to add a new final widget to "know" about the layout and code accordingly: in case (a) it must know not to append the new widget but rather insert it one before the the final spacer while in case (b) the stretch on the current final item must be removed and added to the newly added final item.

                  What I want or expect is there should be an attribute/property specified once on the whole layout (not on any widget(s)) to say "this runs left to right with no spacing or right-justification", no matter what/when you might add any widgets.

                  Is there such a simple property available on a layout? Have I missed something really easy which does this?

                  P.S.
                  In case anyone says: I have used the Qt "flow layout" example code when I have genuinely wanted multiline flow layout. And that effectively does make each line as I want. But the code for that is way too big/complex for just a single line/horizontal layout where I want widgets laid out left to right with no spacing.

                  B Offline
                  B Offline
                  Bonnie
                  wrote last edited by Bonnie
                  #9

                  @JonB said in Laying out items/widgets without stretching/spacing:

                  I would like, as an example:

                  • A horizontal layout inside some parent widget.
                  • I will want to place some widgets (e.g. QPushButtons and QLabels) on it.
                  • I want all items laid out left to right, taking up their "natural" width, with no stretching/spacing before/between/after them. So the line of them will take up no more width than they need, they will be "packed" from left to right and there will be a gap/nothing to the right of them.

                  It is actually possible. Just using a QHBoxLayout and call setAlignment(Qt::AlignLeft) on it, also all the widgets in it should not be set to be stretching/expanding.

                  From https://doc.qt.io/qt-6/qlayoutitem.html#setAlignment:

                  Note: Item alignment is only supported by QLayoutItem subclasses where it would have a visual effect. Except for QSpacerItem, which provides blank space for layouts, all public Qt classes that inherit QLayoutItem support item alignment.

                  And from https://doc.qt.io/qt-6/qboxlayout.html#addWidget (this explains alignment's effect):

                  The default alignment is 0, which means that the widget fills the entire cell.

                  This should work in QBoxLayout and QGridLayout. But there's one QLayout subclass I've found that item alignment doesn't work in it, is QStackedLayout.

                  JonBJ 2 Replies Last reply
                  4
                  • B Bonnie

                    @JonB said in Laying out items/widgets without stretching/spacing:

                    I would like, as an example:

                    • A horizontal layout inside some parent widget.
                    • I will want to place some widgets (e.g. QPushButtons and QLabels) on it.
                    • I want all items laid out left to right, taking up their "natural" width, with no stretching/spacing before/between/after them. So the line of them will take up no more width than they need, they will be "packed" from left to right and there will be a gap/nothing to the right of them.

                    It is actually possible. Just using a QHBoxLayout and call setAlignment(Qt::AlignLeft) on it, also all the widgets in it should not be set to be stretching/expanding.

                    From https://doc.qt.io/qt-6/qlayoutitem.html#setAlignment:

                    Note: Item alignment is only supported by QLayoutItem subclasses where it would have a visual effect. Except for QSpacerItem, which provides blank space for layouts, all public Qt classes that inherit QLayoutItem support item alignment.

                    And from https://doc.qt.io/qt-6/qboxlayout.html#addWidget (this explains alignment's effect):

                    The default alignment is 0, which means that the widget fills the entire cell.

                    This should work in QBoxLayout and QGridLayout. But there's one QLayout subclass I've found that item alignment doesn't work in it, is QStackedLayout.

                    JonBJ Online
                    JonBJ Online
                    JonB
                    wrote last edited by
                    #10

                    @Bonnie said in Laying out items/widgets without stretching/spacing:

                    Just using a QHBoxLayout and call setAlignment(Qt::AlignLeft) on it

                    Hey, that might be 100% just what I was looking for! I looked for some sort of "alignment" but couldn't spot it, maybe because it's on some subclass, even though I thought I checked there. This sounds much more reasonable, will try it soon and report back....

                    1 Reply Last reply
                    0
                    • B Bonnie

                      @JonB said in Laying out items/widgets without stretching/spacing:

                      I would like, as an example:

                      • A horizontal layout inside some parent widget.
                      • I will want to place some widgets (e.g. QPushButtons and QLabels) on it.
                      • I want all items laid out left to right, taking up their "natural" width, with no stretching/spacing before/between/after them. So the line of them will take up no more width than they need, they will be "packed" from left to right and there will be a gap/nothing to the right of them.

                      It is actually possible. Just using a QHBoxLayout and call setAlignment(Qt::AlignLeft) on it, also all the widgets in it should not be set to be stretching/expanding.

                      From https://doc.qt.io/qt-6/qlayoutitem.html#setAlignment:

                      Note: Item alignment is only supported by QLayoutItem subclasses where it would have a visual effect. Except for QSpacerItem, which provides blank space for layouts, all public Qt classes that inherit QLayoutItem support item alignment.

                      And from https://doc.qt.io/qt-6/qboxlayout.html#addWidget (this explains alignment's effect):

                      The default alignment is 0, which means that the widget fills the entire cell.

                      This should work in QBoxLayout and QGridLayout. But there's one QLayout subclass I've found that item alignment doesn't work in it, is QStackedLayout.

                      JonBJ Online
                      JonBJ Online
                      JonB
                      wrote last edited by
                      #11

                      @Bonnie
                      I have now had a chance to play with this. hlayout->setAlignment(Qt::AlignLeft) was 100% what I had in mind (and e.g. AlignRight or AlignHCenter)! Thank you, I just could not find it. Marking your post as the correct answer.

                      I really don't know why other people/Googling/ChatGPT don't seem to mention this, and all claim you need to do it with "spacers" or "stretchers". Those are cumbersome when QLayoutItem::setAlignment() is simpler and better at the job....

                      1 Reply Last reply
                      0
                      • JonBJ JonB has marked this topic as solved

                      • Login

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