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. Stretch prevent widgets from being centered
Forum Updated to NodeBB v4.3 + New Features

Stretch prevent widgets from being centered

Scheduled Pinned Locked Moved Unsolved General and Desktop
14 Posts 3 Posters 3.1k Views
  • 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.
  • D Offline
    D Offline
    deleted475
    wrote on last edited by
    #1

    I have a vertical layout with the nested horizontal one in the bottom. Everything's ok until I add stretches to the latter one to keep the label and the button closer - they prevent the other widgets from being centered. What's the cause of this behavior?

    Screenshot_2022-04-22_03-18-59.png

    Screenshot_2022-04-22_03-19-50.png

    JonBJ 1 Reply Last reply
    0
    • D deleted475

      I have a vertical layout with the nested horizontal one in the bottom. Everything's ok until I add stretches to the latter one to keep the label and the button closer - they prevent the other widgets from being centered. What's the cause of this behavior?

      Screenshot_2022-04-22_03-18-59.png

      Screenshot_2022-04-22_03-19-50.png

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

      @Kenticent
      Do you mean you added just one stretch between ... account? label and Sign Up link? No other stretches?

      D 1 Reply Last reply
      0
      • JonBJ JonB

        @Kenticent
        Do you mean you added just one stretch between ... account? label and Sign Up link? No other stretches?

        D Offline
        D Offline
        deleted475
        wrote on last edited by deleted475
        #3

        @JonB Yes. I didn't find a way to combine the writings while making only one of them clickable, so I separated them into QLabel and QPushButton. The purpose of the stretches is to bring them closer. There are only 2 of them at the bottom - no more others. Here's the code. I think you can guess which widget name corresponds to which GUI element.

            QVBoxLayout *verLayout = new QVBoxLayout;
            QHBoxLayout *horLayout = new QHBoxLayout;
            horLayout->setContentsMargins(0, 0, 0, 0);
            horLayout->setSpacing(0);
        //    horLayout->addStretch();
            horLayout->addWidget(lbl_);
            horLayout->addWidget(btn1_);
        //    horLayout->addStretch();
        
            verLayout->setContentsMargins(0, 0, 0, 0);
            verLayout->setSpacing(40);
            verLayout->setAlignment(Qt::AlignCenter);
            verLayout->addWidget(lbl);
            verLayout->addWidget(usernameLe_);
            verLayout->addWidget(passwordLe_);
            verLayout->addWidget(chk_);
            verLayout->addWidget(btn_);
            verLayout->addLayout(horLayout);
            setLayout(verLayout);
        
        JonBJ 2 Replies Last reply
        0
        • D deleted475

          @JonB Yes. I didn't find a way to combine the writings while making only one of them clickable, so I separated them into QLabel and QPushButton. The purpose of the stretches is to bring them closer. There are only 2 of them at the bottom - no more others. Here's the code. I think you can guess which widget name corresponds to which GUI element.

              QVBoxLayout *verLayout = new QVBoxLayout;
              QHBoxLayout *horLayout = new QHBoxLayout;
              horLayout->setContentsMargins(0, 0, 0, 0);
              horLayout->setSpacing(0);
          //    horLayout->addStretch();
              horLayout->addWidget(lbl_);
              horLayout->addWidget(btn1_);
          //    horLayout->addStretch();
          
              verLayout->setContentsMargins(0, 0, 0, 0);
              verLayout->setSpacing(40);
              verLayout->setAlignment(Qt::AlignCenter);
              verLayout->addWidget(lbl);
              verLayout->addWidget(usernameLe_);
              verLayout->addWidget(passwordLe_);
              verLayout->addWidget(chk_);
              verLayout->addWidget(btn_);
              verLayout->addLayout(horLayout);
              setLayout(verLayout);
          
          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @Kenticent
          Oh I see, you are adding 2 stretches, one before the label and one after the link.

          Then the problem is those stretches will take up the maximum amount of room. And that will make the horizontal they are in occupy as much room as possible, which will be the whole width; hence the horizontals above it now get pushed to the left. That is the reason for what you see.

          horLayout->setSpacing(0);
          

          I am a little surprised this does not produce the minimal distance you want. I don't know why putting in a stretch either side actually makes the spacing any smaller than the 0 you specified. An expert may comment.

          I never understand/know about Qt's layout spacing/stretching/sizing etc. rules, I just play till I get what I want! Certainly just having those stretches at beginning & end will cause the horizontal layout to be too wide. Does horLayout->setSizeConstraint(QLayout::SetMinimumSize) (or maybe QLayout::SetFixedSize --- actually, despite its name, I think this might be just what you want) help? Why not go into Qt Designer and play there with your layouts till they are right, then just take the required generated code and put it into your explicit code, that's the sort of thing I do.

          1 Reply Last reply
          1
          • Christian EhrlicherC Offline
            Christian EhrlicherC Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #5

            A hboxlayout with spacer left and right of the inner widget and it should stay centered

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            1 Reply Last reply
            0
            • D deleted475

              @JonB Yes. I didn't find a way to combine the writings while making only one of them clickable, so I separated them into QLabel and QPushButton. The purpose of the stretches is to bring them closer. There are only 2 of them at the bottom - no more others. Here's the code. I think you can guess which widget name corresponds to which GUI element.

                  QVBoxLayout *verLayout = new QVBoxLayout;
                  QHBoxLayout *horLayout = new QHBoxLayout;
                  horLayout->setContentsMargins(0, 0, 0, 0);
                  horLayout->setSpacing(0);
              //    horLayout->addStretch();
                  horLayout->addWidget(lbl_);
                  horLayout->addWidget(btn1_);
              //    horLayout->addStretch();
              
                  verLayout->setContentsMargins(0, 0, 0, 0);
                  verLayout->setSpacing(40);
                  verLayout->setAlignment(Qt::AlignCenter);
                  verLayout->addWidget(lbl);
                  verLayout->addWidget(usernameLe_);
                  verLayout->addWidget(passwordLe_);
                  verLayout->addWidget(chk_);
                  verLayout->addWidget(btn_);
                  verLayout->addLayout(horLayout);
                  setLayout(verLayout);
              
              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #6

              @Kenticent
              Ah, so I think @Christian-Ehrlicher is saying horLayout->addSpacing(0) (is that right? addSpacing() with 0, or a big number?) where you currently have the two horLayout->addStretch()s? I guess stretches expand the layout container, which you don't want, but spacers reside inside the natural size of the layout.

              Christian EhrlicherC 1 Reply Last reply
              0
              • JonBJ JonB

                @Kenticent
                Ah, so I think @Christian-Ehrlicher is saying horLayout->addSpacing(0) (is that right? addSpacing() with 0, or a big number?) where you currently have the two horLayout->addStretch()s? I guess stretches expand the layout container, which you don't want, but spacers reside inside the natural size of the layout.

                Christian EhrlicherC Offline
                Christian EhrlicherC Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by Christian Ehrlicher
                #7

                @JonB said in Stretch prevent widgets from being centered:

                (is that right? addSpacing() with 0, or a big number?)

                Neither -> QSpacerItem

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                JonBJ 1 Reply Last reply
                1
                • Christian EhrlicherC Christian Ehrlicher

                  @JonB said in Stretch prevent widgets from being centered:

                  (is that right? addSpacing() with 0, or a big number?)

                  Neither -> QSpacerItem

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

                  @Christian-Ehrlicher
                  I thought addSpacing() creates a QSpacerItem? And the docs say:

                  Normally, you don't need to use this class directly. Qt's built-in layout managers provide the following functions for manipulating empty space in layouts:

                  Class Functions

                  QHBoxLayout addSpacing(), addStretch(), insertSpacing(), insertStretch()

                  Anyway, if QSpacerItem

                  QSpacerItem::QSpacerItem(int w, int h, QSizePolicy::Policy hPolicy = QSizePolicy::Minimum, QSizePolicy::Policy vPolicy = QSizePolicy::Minimum)

                  requires a width (and height), so the question is: is that width 0 or large?

                  Christian EhrlicherC 1 Reply Last reply
                  1
                  • JonBJ JonB

                    @Christian-Ehrlicher
                    I thought addSpacing() creates a QSpacerItem? And the docs say:

                    Normally, you don't need to use this class directly. Qt's built-in layout managers provide the following functions for manipulating empty space in layouts:

                    Class Functions

                    QHBoxLayout addSpacing(), addStretch(), insertSpacing(), insertStretch()

                    Anyway, if QSpacerItem

                    QSpacerItem::QSpacerItem(int w, int h, QSizePolicy::Policy hPolicy = QSizePolicy::Minimum, QSizePolicy::Policy vPolicy = QSizePolicy::Minimum)

                    requires a width (and height), so the question is: is that width 0 or large?

                    Christian EhrlicherC Offline
                    Christian EhrlicherC Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    @JonB said in Stretch prevent widgets from being centered:

                    s that width 0 or large?

                    0, Expanding

                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                    Visit the Qt Academy at https://academy.qt.io/catalog

                    JonBJ 1 Reply Last reply
                    1
                    • Christian EhrlicherC Christian Ehrlicher

                      @JonB said in Stretch prevent widgets from being centered:

                      s that width 0 or large?

                      0, Expanding

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

                      @Christian-Ehrlicher
                      Got it! Looks like addSpacing(0) does QSizePolicy::Fixed or similar, and you want QSizePolicy::Expanding, hence you want to create a QSpacerItem yourself, right?

                      1 Reply Last reply
                      1
                      • Christian EhrlicherC Offline
                        Christian EhrlicherC Offline
                        Christian Ehrlicher
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        @JonB said in Stretch prevent widgets from being centered:

                        ence you want to create a QSpacerItem yourself, right?

                        I never work with spacings so I can't say - adding a QSpacerItem is imo easier to understand.

                        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                        Visit the Qt Academy at https://academy.qt.io/catalog

                        JonBJ 1 Reply Last reply
                        0
                        • Christian EhrlicherC Christian Ehrlicher

                          @JonB said in Stretch prevent widgets from being centered:

                          ence you want to create a QSpacerItem yourself, right?

                          I never work with spacings so I can't say - adding a QSpacerItem is imo easier to understand.

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

                          @Christian-Ehrlicher
                          :) I quoted from the doc page for QSpacerItem:

                          Normally, you don't need to use this class directly. Qt's built-in layout managers provide the following functions for manipulating empty space in layouts:

                          Maybe you are not "normal" ;-)

                          1 Reply Last reply
                          0
                          • D Offline
                            D Offline
                            deleted475
                            wrote on last edited by deleted475
                            #13

                            @JonB @Christian-Ehrlicher Thank you for participating in discussion! I figured out, that despite the ctor of QSpacerItem having Minimum size policy as default parameter, addSpacing() sets one side to Fixed depending on the orientation of the Layout. For the horizontal one it goes as follows.

                            QLayoutPrivate::createSpacerItem(this, size, 0, QSizePolicy::Fixed, QSizePolicy::Minimum)
                            

                            Full source code https://code.woboq.org/qt5/qtbase/src/widgets/kernel/qboxlayout.cpp.html#_ZN10QBoxLayout13insertSpacingEii

                            So if you want to have Expanding horizontal policy, you have to set it yourself. But if you look at the source code code of addStretch() - that's exactly what it does (creates QSpacerItem with size of 0 and expanding size policy).

                            Additionally, I figured out that I can 'glue' those two widgets together by setting the alignment of the QHBoxLayout to AlignHCenter.

                            In summary,

                            horLayout->setSpacing(0);
                            horLayout->setAlignment(Qt::AlignHCenter);
                            

                            should do the trick. Thank you very much again.

                            JonBJ 1 Reply Last reply
                            0
                            • D deleted475

                              @JonB @Christian-Ehrlicher Thank you for participating in discussion! I figured out, that despite the ctor of QSpacerItem having Minimum size policy as default parameter, addSpacing() sets one side to Fixed depending on the orientation of the Layout. For the horizontal one it goes as follows.

                              QLayoutPrivate::createSpacerItem(this, size, 0, QSizePolicy::Fixed, QSizePolicy::Minimum)
                              

                              Full source code https://code.woboq.org/qt5/qtbase/src/widgets/kernel/qboxlayout.cpp.html#_ZN10QBoxLayout13insertSpacingEii

                              So if you want to have Expanding horizontal policy, you have to set it yourself. But if you look at the source code code of addStretch() - that's exactly what it does (creates QSpacerItem with size of 0 and expanding size policy).

                              Additionally, I figured out that I can 'glue' those two widgets together by setting the alignment of the QHBoxLayout to AlignHCenter.

                              In summary,

                              horLayout->setSpacing(0);
                              horLayout->setAlignment(Qt::AlignHCenter);
                              

                              should do the trick. Thank you very much again.

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

                              @Kenticent
                              Like I said, personally I find half of the Qt layout stuff guesswork/divine inspiration/brain-ache, and address it with trail-and-error/use the Designer till I get it right :)

                              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