Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Layout issue



  • This is the UI:

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
    <class>MainWindow</class>
    <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>567</width>
        <height>492</height>
       </rect>
      </property>
      <property name="sizePolicy">
       <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="windowTitle">
       <string>Trainer Server</string>
      </property>
      <widget class="QWidget" name="centralWidget">
       <property name="sizePolicy">
        <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <layout class="QGridLayout" name="gridLayout">
        <item row="0" column="0" colspan="4">
         <layout class="QHBoxLayout" name="phszloTop">
          <item>
           <widget class="QPushButton" name="pbtnAdmin">
            <property name="sizePolicy">
             <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
              <horstretch>0</horstretch>
              <verstretch>0</verstretch>
             </sizepolicy>
            </property>
            <property name="font">
             <font>
              <pointsize>9</pointsize>
             </font>
            </property>
            <property name="contextMenuPolicy">
             <enum>Qt::NoContextMenu</enum>
            </property>
            <property name="text">
             <string>&amp;Admin...</string>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QPushButton" name="pbtnSearch">
            <property name="sizePolicy">
             <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
              <horstretch>0</horstretch>
              <verstretch>0</verstretch>
             </sizepolicy>
            </property>
            <property name="font">
             <font>
              <pointsize>9</pointsize>
             </font>
            </property>
            <property name="contextMenuPolicy">
             <enum>Qt::NoContextMenu</enum>
            </property>
            <property name="text">
             <string>&amp;Search...</string>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QPushButton" name="pbtnBeginSession">
            <property name="sizePolicy">
             <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
              <horstretch>0</horstretch>
              <verstretch>0</verstretch>
             </sizepolicy>
            </property>
            <property name="font">
             <font>
              <pointsize>9</pointsize>
             </font>
            </property>
            <property name="contextMenuPolicy">
             <enum>Qt::NoContextMenu</enum>
            </property>
            <property name="text">
             <string>&amp;Begin Session</string>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QPushButton" name="pbtnEndSession">
            <property name="sizePolicy">
             <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
              <horstretch>0</horstretch>
              <verstretch>0</verstretch>
             </sizepolicy>
            </property>
            <property name="font">
             <font>
              <pointsize>9</pointsize>
             </font>
            </property>
            <property name="contextMenuPolicy">
             <enum>Qt::NoContextMenu</enum>
            </property>
            <property name="text">
             <string>&amp;End Session</string>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QLabel" name="lblTtoV">
            <property name="sizePolicy">
             <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
              <horstretch>0</horstretch>
              <verstretch>0</verstretch>
             </sizepolicy>
            </property>
            <property name="layoutDirection">
             <enum>Qt::LeftToRight</enum>
            </property>
            <property name="text">
             <string>Select Trainee to View:</string>
            </property>
            <property name="alignment">
             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QComboBox" name="cboTraineeToView">
            <property name="sizePolicy">
             <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
              <horstretch>0</horstretch>
              <verstretch>0</verstretch>
             </sizepolicy>
            </property>
           </widget>
          </item>
         </layout>
        </item>
        <item row="1" column="0" colspan="4">
         <layout class="QGridLayout" name="pgrdloContent">
          <property name="leftMargin">
           <number>6</number>
          </property>
          <property name="topMargin">
           <number>6</number>
          </property>
          <property name="rightMargin">
           <number>6</number>
          </property>
          <property name="bottomMargin">
           <number>6</number>
          </property>
         </layout>
        </item>
       </layout>
      </widget>
    </widget>
    <layoutdefault spacing="6" margin="11"/>
    <resources/>
    <connections/>
    </ui>
    

    And this is what it looks like in the application:
    image001.png
    The labels Ground Truth and Trainee Marks are setup in the same QGridLayout as the widgets below:

        QLabel* plblGroundTruths = new QLabel("Ground Truth", this);
        plblGroundTruths->setStyleSheet("font-weight: bold;");
        plblGroundTruths->setAlignment(Qt::AlignHCenter);
        truth* pGroundTruth = new truth(this);
        QLabel* plblTraineeMarks = new QLabel("Trainee Marks", this);
        plblTraineeMarks->setStyleSheet("font-weight: bold;");
        plblTraineeMarks->setAlignment(Qt::AlignHCenter);
        truth* pTraineeMarks = new truth(this);   
        //Remove widgets from layout
        removeContent(mpui->pgrdloContent);
        //Add the content to the layout
        mpui->pgrdloContent->addWidget(plblGroundTruths, 0, 1);
        mpui->pgrdloContent->addWidget(plblTraineeMarks, 0, 2);
        mpui->pgrdloContent->addLayout(pfrmloMain, 1, 0);
        mpui->pgrdloContent->addWidget(pGroundTruth, 1, 1);
        mpui->pgrdloContent->addWidget(pTraineeMarks, 1, 2);
    

    However for some reason which escapes me, there is a gap between the labels and the widgets below them when I resize the window, the gap gets bigger, why?

    [Edit] I've modified the lines:

        plblGroundTruths->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
        plblTraineeMarks->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
    

    Now there is no gap between the labels and the widgets underneath, now the gap is above the labels and if I resize the window the gap increases in size, what is missing?

    [Edit 2] I've added a verticalSpacer under the QGridLayout and now there is no gap, but the vertical size of the QGridLayout does not adjust to the size of the window vertically ?



  • @SPlatten
    My last attempt, because I'm going out, and someone who knows designer better than me can doubtless say.

    The stretch needs to be set on the layout items added to the enclosing vboxlayout. That (the vboxlayout) has stretch factors doesn't it, or not? Temporarily put a stretch of 1 for its first first item, the hbox, and a stretch of 100 for its second item, the gridlayout? That's probably not fully right but does it do what you want? Else I don't know which way to do it.



  • @SPlatten

    I don't know, if it's just me but I'm personally not a big fan of QGridLayouts. I would use cascading HBox + VBox Layouts in 99% of the cases.

    As I can tell from your picture, you have the same (or similar) issues, you had with your "Select Trainee" label, inside your Alarms GroupBox. The words "error" and "temperatur" are not shown completely.

    @SPlatten said in Layout issue:

    but the vertical size of the QGridLayout does not adjust to the size of the window vertically ?

    Because the Grid shares the expansion of width and/or height with all elements in the grid (depending on your size policies and size hints). So, I guess, it's because of the space the two labels above the two black boxes take.

    Edit:

    @SPlatten said in Layout issue:

    [Edit 2] I've added a verticalSpacer under the QGridLayout and now there is no gap

    In addition: The spacer "swallows" your movement in vertical direction. The spacer keeps getting bigger and pushes the widgets above him further to the top.



  • @Pl45m4 , thank you I will investigate.



  • @Pl45m4 , still an issue, the initial layout:
    image001.png
    After dragging out the top:
    image002.png
    What I want to happen is for the bottom layout to stay joined to just under the horizontal layout where the buttons are, so it expands. So far everything I've tried has failed. The top layout that contains the button and the combo is QHBoxLayout, the layout that contains everything else under the horizontal layout is a QGridLayout.

    Dragging out horizontally is not a problem and everything works beautifully, its just vertical where the QGridLayout does not resize.



  • @SPlatten , bump, can anyone help?



  • @SPlatten , Is this achievable?



  • @SPlatten
    Presumably you actually mean that the whole widget has a QVBoxLayout, containing a QHBoxLayout for the button row and a QGridLayout for the bottom stuff. If, as I understand it, you want to resize the outer widget vertically and have the QGridLayout area remain near the top, don't you just want a stretch after the grid layout?



  • @JonB , looking at the ui file the structure is:

    MainWindow            QMainWindow
      phzloTop            QHBoxLayout
        cboTraineeToView  QComboBox
        lblTtoV           QLabel
        pbtnAdmin         QPushButton
        pbtnBeginSession  QPushButton
        pbtnEndSession    QPushButton
        pbtnSearch        QPushButton
      pgrdloContent       QGridLayout
    

    The widgets that appear in the QGridLayout are define in a database and added to the layout at runtime. There are various instances of QVBoxLayout and QFormLayout used to layout the data on the left of the grid.



  • @SPlatten
    I don't really understand how the main window has a QHBoxLayout followed by a QGridLayout without being enclosed in a QVBoxLayout, and how you achieved it in the designer. What makes the QGridLayout come below the QHBoxLayout rather than, say, to the right of it?

    In any case, if I understand what you want correctly, I would have done:

    QVBoxLayout
        QHBoxLayout
        QGridLayout
        addStretch()
    

    But maybe I'm wrong or don't understand.



  • @JonB, thank you, I'll give it a try.



  • @JonB , I've added a QVBoxLayout at top level in the centralWidget, I've then dragged and dropped the QHBoxLayout and QGridLayout into this, I've edited the properties for the QVBoxLayout setting layoutStretch to 1,1.

    Unfortunately its still the same as it was before adding the QVBoxLayout where horizontally everything is great, but vertically the button bar moves with the top of the window but the QGridLayout does not.

    Also in code for the QGridLayout after I have populated it:

    mpui->pgrdloContent->setRowStretch(0, 1);
    mpui->pgrdloContent->setRowStretch(1, 1);
    


  • @SPlatten said in Layout issue:

    I've edited the properties for the QVBoxLayout setting layoutStretch to 1,1.

    But that makes them have the same stretch as each other, exactly as they do and you don't want. I said to add a stretch after the QGridLayout as per what I wrote, that's the whole point?



  • @JonB , Either we have crossed over or I'm not understanding what you are saying I've added a stretch to the QGridLayout, isn't that exactly what this does?:

    mpui->pgrdloContent->setRowStretch(0, 1);
    mpui->pgrdloContent->setRowStretch(1, 1);
    


  • @SPlatten
    No. Exactly as I wrote. 3 things: a horizontal layout, then a grid layout, then a stretch.

    Why don't you practice with just a vertical layout containing two horizontal layouts and a stretch? That's what you want, right? I can't see how the grid layout being a grid is relevant.



  • @JonB , I have:

    MainWindow              QMainWindow
      pvtloMain             QVBoxLayout
        phzloTop            QHBoxLayout
          cboTraineeToView  QComboBox
          lblTtoV           QLabel
          pbtnAdmin         QPushButton
          pbtnBeginSession  QPushButton
          pbtnEndSession    QPushButton
          pbtnSearch        QPushButton
        pgrdloContent       QGridLayout
    


  • @SPlatten
    I have already answered this 3 times. I said you need a stretch after the grid layout, assuming I understand what you want. I can't say it any more.



  • @JonB, what is a stretch? I don't see it in the side bar, under which group should I find that?



  • @SPlatten
    I don't run Designer but it's there on the toolbar. Horizontal & vertical stretchers. They look like blue stretches when you place them. They should end up generating

    vertLayout.addStretch()
    

    I think/assume. void QBoxLayout::addStretch(int stretch = 0).



  • @JonB

    Spacers not stretch :)
    Stretch is the stretch factor to stretch a layout item over multiple layout "slots"



  • @Pl45m4
    I have written what I thought it was. I thought spacers were fixed size. Anyway whichever you say! It's some blue thing in Designer :) The link I gave for addStretch() states:

    Adds a stretchable space (a QSpacerItem) with zero minimum size and stretch factor stretch to the end of this box layout.

    Isn't that it?



  • @JonB I'm running version 5.9.2 of Qt Designer, there is no stretchers...Spacers there is thank you @Pl45m4 , but I don't want to spacer things out stretch is the correct terminology just don't see it.

    I have now modified the source adding a call to:

    mpui->pvtloMain->addStretch(1);
    

    Ok, now with this its different, the whilespace between the QHBoxLayout layout and QGridLayout is now gone and when resizing the grid layout moves with the window, unlike before when it stayed anchored to the bottom, however its still not right because its not "stretching" the content, instead is moves up the window with space under the layout not occupied.

    Just to be absolutely clear I don't want space, I want the content of the QGridLayout to resize as the container is dragged. In the same way it already does when dragging out horizontally.



  • @SPlatten said in Layout issue:

    Just to be absolutely clear I don't want space, I want the content of the QGridLayout to resize as the container is dragged.

    I had no idea that was what you wanted. That's why I asked each time.

    So I think you need to set the grid layout (as a whole, not an individual row) to occupy as much height as possible. Now is that what you want?



  • @JonB , ok, please elaborate, its sounds like thats what I need, how do I do that?



  • @SPlatten
    Dunno, I just play till I get what I want :) At least we finally seem to be agreeing about what that is!

    Don't you have to set the grid in the vertical layout to expand its height as much as possible?

    Is QBoxLayout::addLayout(QLayout *layout, int stretch = 0) what is wanted? With a non-0 stretch.

    Otherwise maybe @Pl45m4 can state what is wanted here?


  • Moderators

    @SPlatten

    assuming:

    MainWindow              QMainWindow
      pvtloMain             QVBoxLayout
        phzloTop            QHBoxLayout
          cboTraineeToView  QComboBox
          lblTtoV           QLabel
          pbtnAdmin         QPushButton
          pbtnBeginSession  QPushButton
          pbtnEndSession    QPushButton
          pbtnSearch        QPushButton
        pgrdloContent       QGridLayout
    

    pvtloMain->setStretch(0, 0);
    pvtloMain->setStretch(1, 1);

    that makes phzloTop take up as little space as possible and pgrdloContent as much as possible



  • @J-Hilk , I've removed both of those lines and the result is the same, they did nothing.



  • @JonB The QGridLayout is added to the QVBoxLayout in the designer, I cannot set the layoutRowStretch property, trying to set it to 1, it goes right back to 0 after I press enter.



  • @SPlatten
    My last attempt, because I'm going out, and someone who knows designer better than me can doubtless say.

    The stretch needs to be set on the layout items added to the enclosing vboxlayout. That (the vboxlayout) has stretch factors doesn't it, or not? Temporarily put a stretch of 1 for its first first item, the hbox, and a stretch of 100 for its second item, the gridlayout? That's probably not fully right but does it do what you want? Else I don't know which way to do it.


  • Moderators

    @SPlatten than they layouts or widgets are otherwise constraint

    did you set max height of the Gridlayout ? or the sizepolicy to fixed ?

    because a default arrangement works as intended:

    10570056-aaf9-476f-82cc-716c36e5f2b8-image.png



  • @J-Hilk
    Thank you for rescuing me here! I leave you to deal further with the question ;-)



  • @JonB, the QVboxLayout has the property layoutStretch with I've changed from 0,0 to 1,100.

    Thats the puzzle solved! It works perfectly, thank you for your help and support.


Log in to reply