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. Fixed width inside a QVBoxLayout?
Forum Updated to NodeBB v4.3 + New Features

Fixed width inside a QVBoxLayout?

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 2 Posters 12.5k Views 1 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.
  • J Offline
    J Offline
    JonB
    wrote on 3 Jan 2018, 12:27 last edited by JonB 1 Mar 2018, 12:34
    #1
    1. I have a VBoxLayout.
    2. I add a number of QPushButtons, with varying length text, onto it.
    3. At present that gives me varying width buttons.
    4. I would like them all to be the same width.
    5. I would like to achieve this with "minimal code", e.g. I'd prefer not to have to do anything to each button.

    So, can I set something on the VBoxLayout which would cause the buttons to expand to its width? (I'd be prepared to add a VBoxFrame, if that would make any difference.) I'd like the container to tell the button contents to all expand to same width.

    [I think I can see this achieved on other pages in the 32K-lines of code I've inherited, but it gets so complicated to figure how they are achieving it but this page is not.]

    V 1 Reply Last reply 3 Jan 2018, 12:41
    0
    • V Offline
      V Offline
      VRonin
      wrote on 3 Jan 2018, 12:36 last edited by
      #2

      This is very strange. if you don't insert spacers or hand code the maximum size of the button this shouldn't be possible.

      You could try the below but I doubt it will work.
      Can you show a snippet of how you add those buttons to the layout?
      are you calling QPushButton::setMaximumSize or QPushButton::setMaximumWidth?

      for(int i=0;i<layout->count();++i){
      QWidget* const currWid = layout->itemAt(i)->widget();
      if(!currWid) continue;
      currWid->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred);
      }
      

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      J 1 Reply Last reply 3 Jan 2018, 12:44
      0
      • J JonB
        3 Jan 2018, 12:27
        1. I have a VBoxLayout.
        2. I add a number of QPushButtons, with varying length text, onto it.
        3. At present that gives me varying width buttons.
        4. I would like them all to be the same width.
        5. I would like to achieve this with "minimal code", e.g. I'd prefer not to have to do anything to each button.

        So, can I set something on the VBoxLayout which would cause the buttons to expand to its width? (I'd be prepared to add a VBoxFrame, if that would make any difference.) I'd like the container to tell the button contents to all expand to same width.

        [I think I can see this achieved on other pages in the 32K-lines of code I've inherited, but it gets so complicated to figure how they are achieving it but this page is not.]

        V Offline
        V Offline
        VRonin
        wrote on 3 Jan 2018, 12:41 last edited by
        #3

        @JonB said in Fixed width inside a QVBoxLayout?:

        but it gets so complicated to figure how they are achieving it

        Simple snippet that shows it working

        #include <QApplication>
        #include <QWidget>
        #include <QVBoxLayout>
        #include <QPushButton>
        int main(int argc, char *argv[])
        {
            QApplication a(argc, argv);
            QWidget mainWid;
            QVBoxLayout* mainLay=new QVBoxLayout(&mainWid);
            for(int i=0;i<5;++i){
                const QString randomString((rand()%20)+1,QChar('a'));
                QPushButton* button =new QPushButton(randomString,&mainWid);
                mainLay->addWidget(button);
            }
            mainWid.show();
            return a.exec();
        
        }
        

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        1 Reply Last reply
        1
        • V VRonin
          3 Jan 2018, 12:36

          This is very strange. if you don't insert spacers or hand code the maximum size of the button this shouldn't be possible.

          You could try the below but I doubt it will work.
          Can you show a snippet of how you add those buttons to the layout?
          are you calling QPushButton::setMaximumSize or QPushButton::setMaximumWidth?

          for(int i=0;i<layout->count();++i){
          QWidget* const currWid = layout->itemAt(i)->widget();
          if(!currWid) continue;
          currWid->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred);
          }
          
          J Offline
          J Offline
          JonB
          wrote on 3 Jan 2018, 12:44 last edited by JonB 1 Mar 2018, 12:47
          #4

          @VRonin
          I will have to investigate the exact code. Trouble is, there's loads on the pages that don't work, and loads on the pages that do!

          No calls to set size at all.

          Your suggestion(?) of code is exactly what I would like not to do, as it makes a call of setSizePolicy() on each widget/button. I am hoping I can set something on the container only, and the child widgets will expand to fit.

          [EDIT: @VRonin So, you are stating that the default(?) behaviour of a QPushButton placed on a QVBoxLayout is already that it should expand width to size of QVBoxLayout, rather than adopt (minimum) width corresponding to button's text? Please make that clear to me, one way or the other, thanks.]

          V 1 Reply Last reply 3 Jan 2018, 13:04
          0
          • J JonB
            3 Jan 2018, 12:44

            @VRonin
            I will have to investigate the exact code. Trouble is, there's loads on the pages that don't work, and loads on the pages that do!

            No calls to set size at all.

            Your suggestion(?) of code is exactly what I would like not to do, as it makes a call of setSizePolicy() on each widget/button. I am hoping I can set something on the container only, and the child widgets will expand to fit.

            [EDIT: @VRonin So, you are stating that the default(?) behaviour of a QPushButton placed on a QVBoxLayout is already that it should expand width to size of QVBoxLayout, rather than adopt (minimum) width corresponding to button's text? Please make that clear to me, one way or the other, thanks.]

            V Offline
            V Offline
            VRonin
            wrote on 3 Jan 2018, 13:04 last edited by VRonin 1 Mar 2018, 13:10
            #5

            @JonB said in Fixed width inside a QVBoxLayout?:

            So, you are stating that the default(?) behaviour of a QPushButton placed on a QVBoxLayout is already that it should expand width to size of QVBoxLayout, rather than adopt (minimum) width corresponding to button's text?

            Yes indeed. and not just QPushButton, any widget. It's actually very hard to achieve the opposite

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            J 1 Reply Last reply 3 Jan 2018, 16:16
            0
            • V VRonin
              3 Jan 2018, 13:04

              @JonB said in Fixed width inside a QVBoxLayout?:

              So, you are stating that the default(?) behaviour of a QPushButton placed on a QVBoxLayout is already that it should expand width to size of QVBoxLayout, rather than adopt (minimum) width corresponding to button's text?

              Yes indeed. and not just QPushButton, any widget. It's actually very hard to achieve the opposite

              J Offline
              J Offline
              JonB
              wrote on 3 Jan 2018, 16:16 last edited by JonB 1 Mar 2018, 16:16
              #6

              @VRonin
              I will have to investigate this and get back to you, perhaps tomorrow.

              But I'm still "surprised" at what you say is default behaviour. In a VBoxLayout, I thought that meant Qt lays out each child widget that is added vertically one after the other, but not that it would stretch the widget horizontally to width while doing so. Is that indeed the case? (Well I guess it is because you're saying so, but just seeking to confirm, because I assumed child widgets would only take up their own horizontal width...)

              V 1 Reply Last reply 3 Jan 2018, 16:33
              0
              • J JonB
                3 Jan 2018, 16:16

                @VRonin
                I will have to investigate this and get back to you, perhaps tomorrow.

                But I'm still "surprised" at what you say is default behaviour. In a VBoxLayout, I thought that meant Qt lays out each child widget that is added vertically one after the other, but not that it would stretch the widget horizontally to width while doing so. Is that indeed the case? (Well I guess it is because you're saying so, but just seeking to confirm, because I assumed child widgets would only take up their own horizontal width...)

                V Offline
                V Offline
                VRonin
                wrote on 3 Jan 2018, 16:33 last edited by
                #7

                @JonB said in Fixed width inside a QVBoxLayout?:

                Is that indeed the case?

                Yes. Proof in the source

                 case TopToBottom:
                                box->item->setGeometry(QRect(s.x(), a.at(i).pos, s.width(), a.at(i).size));
                break;
                

                the s.width() sets the width of every item in the layout to the width of the layout (minus the margins)

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                J 1 Reply Last reply 4 Jan 2018, 09:39
                0
                • V VRonin
                  3 Jan 2018, 16:33

                  @JonB said in Fixed width inside a QVBoxLayout?:

                  Is that indeed the case?

                  Yes. Proof in the source

                   case TopToBottom:
                                  box->item->setGeometry(QRect(s.x(), a.at(i).pos, s.width(), a.at(i).size));
                  break;
                  

                  the s.width() sets the width of every item in the layout to the width of the layout (minus the margins)

                  J Offline
                  J Offline
                  JonB
                  wrote on 4 Jan 2018, 09:39 last edited by JonB 1 Apr 2018, 09:41
                  #8

                  @VRonin
                  Well, today is Thursday, and it does indeed now set the widths of all child widgets to the same as one another. Yesterday I had them only taking up their own individual widths. Does Qt source code have a check for day-of-week for its behaviour?

                  I have learnt that QVBoxLayout's child widgets are stretched to fill the width.
                  You wrote:

                  It's actually very hard to achieve the opposite

                  If elsewhere I do want that behaviour --- use the QVBoxLayout to arrange children vertically but have each child only take up its natural width --- how would I achieve that then? Use a QHBoxLayout for each one??

                  I'm also struggling to understand whether there is "consistency" in the handling of children of QHBoxLayout versus QVBoxLayout. If QVBoxLayout "widens" children to match widest, why is it that (if I, say, make one button's text multi-line vertical or I use setMinimumHeight()) QHboxLayout does not "heighten" other children to match??

                  V 1 Reply Last reply 4 Jan 2018, 10:03
                  0
                  • J JonB
                    4 Jan 2018, 09:39

                    @VRonin
                    Well, today is Thursday, and it does indeed now set the widths of all child widgets to the same as one another. Yesterday I had them only taking up their own individual widths. Does Qt source code have a check for day-of-week for its behaviour?

                    I have learnt that QVBoxLayout's child widgets are stretched to fill the width.
                    You wrote:

                    It's actually very hard to achieve the opposite

                    If elsewhere I do want that behaviour --- use the QVBoxLayout to arrange children vertically but have each child only take up its natural width --- how would I achieve that then? Use a QHBoxLayout for each one??

                    I'm also struggling to understand whether there is "consistency" in the handling of children of QHBoxLayout versus QVBoxLayout. If QVBoxLayout "widens" children to match widest, why is it that (if I, say, make one button's text multi-line vertical or I use setMinimumHeight()) QHboxLayout does not "heighten" other children to match??

                    V Offline
                    V Offline
                    VRonin
                    wrote on 4 Jan 2018, 10:03 last edited by VRonin 1 Apr 2018, 10:05
                    #9

                    @JonB said in Fixed width inside a QVBoxLayout?:

                    Does Qt source code have a check for day-of-week for its behaviour?

                    LOL

                    Use a QHBoxLayout for each one?

                    Yes but not only. you also have to add a spacer (layout->addItem(new QSpacerItem(0,0,QSizePolicy::Expanding,QSizePolicy::Preferred)); or layout->addStretch()) to the left, right or both (depending how you want it aligned)

                    I'm also struggling to understand whether there is "consistency" in the handling of children of QHBoxLayout versus QVBoxLayout.

                    They are the exact same class basically. The only difference is a small internal variable that tells them the direction of the layout, the real code is in their base class QBoxLayout

                    if I, say, make one button's text multi-line vertical or I use setMinimumHeight() QHboxLayout does not "heighten" other children to match??

                    That's because of QPushButton's size policy being QSizePolicy::Fixed for the height. Just add button->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); to make it expand

                    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                    ~Napoleon Bonaparte

                    On a crusade to banish setIndexWidget() from the holy land of Qt

                    J 1 Reply Last reply 4 Jan 2018, 10:21
                    0
                    • V VRonin
                      4 Jan 2018, 10:03

                      @JonB said in Fixed width inside a QVBoxLayout?:

                      Does Qt source code have a check for day-of-week for its behaviour?

                      LOL

                      Use a QHBoxLayout for each one?

                      Yes but not only. you also have to add a spacer (layout->addItem(new QSpacerItem(0,0,QSizePolicy::Expanding,QSizePolicy::Preferred)); or layout->addStretch()) to the left, right or both (depending how you want it aligned)

                      I'm also struggling to understand whether there is "consistency" in the handling of children of QHBoxLayout versus QVBoxLayout.

                      They are the exact same class basically. The only difference is a small internal variable that tells them the direction of the layout, the real code is in their base class QBoxLayout

                      if I, say, make one button's text multi-line vertical or I use setMinimumHeight() QHboxLayout does not "heighten" other children to match??

                      That's because of QPushButton's size policy being QSizePolicy::Fixed for the height. Just add button->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum); to make it expand

                      J Offline
                      J Offline
                      JonB
                      wrote on 4 Jan 2018, 10:21 last edited by JonB 1 Apr 2018, 10:21
                      #10

                      @VRonin

                      1. Yes but not only. you also have to add a spacer

                      Ah ha! Thanks. Very useful.

                      1. That's because of QPushButton's size policy being QSizePolicy::Fixed for the height.

                      Ah ha, again! That would also answer a question I was about to ask: why is it that QPushButton::setMaximumHeight() causes button to occupy maximum height when it does not need it?

                      Now then: Looking at the docs I see no mention that a QPushButton/QAbstractButton etc. has such a size policy. And I program in Python, so I have no desire to download Qt's source code or flip between Python/C++ IDEs to examine it all the time. So now I'm wondering: how many other widget types have undocumented QSizePolicys? I was spending ages trying to understand that QPushButton behaviour.... :(

                      P.S.
                      I'm about to start a separate thread on setting sizes & QCSS. I hope you'll look at that too, as your answers are always prompt & correct!

                      V 1 Reply Last reply 4 Jan 2018, 10:29
                      0
                      • J JonB
                        4 Jan 2018, 10:21

                        @VRonin

                        1. Yes but not only. you also have to add a spacer

                        Ah ha! Thanks. Very useful.

                        1. That's because of QPushButton's size policy being QSizePolicy::Fixed for the height.

                        Ah ha, again! That would also answer a question I was about to ask: why is it that QPushButton::setMaximumHeight() causes button to occupy maximum height when it does not need it?

                        Now then: Looking at the docs I see no mention that a QPushButton/QAbstractButton etc. has such a size policy. And I program in Python, so I have no desire to download Qt's source code or flip between Python/C++ IDEs to examine it all the time. So now I'm wondering: how many other widget types have undocumented QSizePolicys? I was spending ages trying to understand that QPushButton behaviour.... :(

                        P.S.
                        I'm about to start a separate thread on setting sizes & QCSS. I hope you'll look at that too, as your answers are always prompt & correct!

                        V Offline
                        V Offline
                        VRonin
                        wrote on 4 Jan 2018, 10:29 last edited by
                        #11

                        @JonB said in Fixed width inside a QVBoxLayout?:

                        I have no desire to download Qt's source code or flip between Python/C++ IDEs to examine it all the time

                        That's why I find https://code.woboq.org/qt5/ so convenient

                        how many other widget types have undocumented QSizePolicys?

                        All of them I think. they use the size policy that achieves the more natural behaviour (i.e. the one that most apps adopt)

                        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                        ~Napoleon Bonaparte

                        On a crusade to banish setIndexWidget() from the holy land of Qt

                        J 1 Reply Last reply 4 Jan 2018, 10:46
                        0
                        • V VRonin
                          4 Jan 2018, 10:29

                          @JonB said in Fixed width inside a QVBoxLayout?:

                          I have no desire to download Qt's source code or flip between Python/C++ IDEs to examine it all the time

                          That's why I find https://code.woboq.org/qt5/ so convenient

                          how many other widget types have undocumented QSizePolicys?

                          All of them I think. they use the size policy that achieves the more natural behaviour (i.e. the one that most apps adopt)

                          J Offline
                          J Offline
                          JonB
                          wrote on 4 Jan 2018, 10:46 last edited by
                          #12

                          @VRonin
                          I take your point about being able to view Qt source on-line, and have bookmarked your link, thank you.

                          The issue really is that potentially I need to look at the source code in addition to the documentation every time I want to use anything from Qt in case there is important undocumented behaviour like this. I feel it would be helpful if the docs decided to mention what non-default sizing each widget uses. But at least I know where I am in this case.

                          1 Reply Last reply
                          0

                          1/12

                          3 Jan 2018, 12:27

                          • Login

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