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
12 Posts 5 Posters 208 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 Offline
    JonBJ Offline
    JonB
    wrote last edited by
    #1

    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 J.HilkJ B 3 Replies Last reply
    0
    • JonBJ JonB referenced this topic
    • 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
      • 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 Offline
          JonBJ Offline
          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 Offline
              JonBJ Offline
              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 Offline
                  JonBJ Offline
                  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 Offline
                        JonBJ Offline
                        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 Offline
                          JonBJ Offline
                          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....

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

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

                            JoeCFDJ Offline
                            JoeCFDJ Offline
                            JoeCFD
                            wrote last edited by JoeCFD
                            #12

                            @JonB you can use setAlignment(Qt::AlignLeft or Qt::AlignRight or Qt::AlignCenter or Qt::AlignTop ...) for different layouts. Sometimes this may not work as you need. Spacer can help a bit more when this setting does not work. Try different chatbots(so many nowadays) if the answers are not good enough. I have not use ChatGPT for quite some time. Also do not trust the replies from the chatbots 100%. Never rely on one chatbot like ChatGPT which often replies with junks.

                            I use setAlignment in my apps. But I still tried grok and deepseek for you with
                            "how to align widgets to left only in qhboxlayout in qt"
                            Only deepseek gives this answer.
                            Method 1: Using setAlignment() on the layout

                            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