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. QGroupBox, QScrollArea, QFormLayout
Forum Updated to NodeBB v4.3 + New Features

QGroupBox, QScrollArea, QFormLayout

Scheduled Pinned Locked Moved Solved General and Desktop
41 Posts 7 Posters 7.0k Views 4 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.
  • SPlattenS SPlatten

    @SGaist , its supposed to be like this:

    QWidget( mpobjErrors )
    -- QVBoxLayout( mpvbloErrors )
    ----- QWidget( pobjFormErrorsContr )
    -------- QScrollArea( fixed height )
    -------- QFormLayout( mpfrmloErrors  )
    ----- QPushButton( pbtnAck )
    

    Where only the QFormLayout is scrollable, but it isn't.

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

    @SPlatten

    ----- QWidget( pobjFormErrorsContr )
    -------- QScrollArea( fixed height )
    -------- QFormLayout( mpfrmloErrors  )
    

    But I/we already said that QScrollArea takes a setWidget(someWidget) for the thing it wants to scroll, which has to be a QWidget not a QLayout.

    Also your QFormLayout is not anywhere descended from QScrollArea, it's a sibling, so it's not inside it, so it won't be subject to scrollability.

    SPlattenS 1 Reply Last reply
    0
    • JonBJ JonB

      @SPlatten

      ----- QWidget( pobjFormErrorsContr )
      -------- QScrollArea( fixed height )
      -------- QFormLayout( mpfrmloErrors  )
      

      But I/we already said that QScrollArea takes a setWidget(someWidget) for the thing it wants to scroll, which has to be a QWidget not a QLayout.

      Also your QFormLayout is not anywhere descended from QScrollArea, it's a sibling, so it's not inside it, so it won't be subject to scrollability.

      SPlattenS Offline
      SPlattenS Offline
      SPlatten
      wrote on last edited by
      #20

      @JonB , see code above:

      mpsaErrors = new QScrollArea;
      mpsaErrors->setWidget(pobjFormErrorsContr);
      

      Kind Regards,
      Sy

      JonBJ 1 Reply Last reply
      0
      • SPlattenS SPlatten

        @JonB , see code above:

        mpsaErrors = new QScrollArea;
        mpsaErrors->setWidget(pobjFormErrorsContr);
        
        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #21

        @SPlatten
        I see your code, my two comments apply to your "diagram", and comparing it to @SGaist's "diagram".

        SPlattenS 1 Reply Last reply
        0
        • JonBJ JonB

          @SPlatten
          I see your code, my two comments apply to your "diagram", and comparing it to @SGaist's "diagram".

          SPlattenS Offline
          SPlattenS Offline
          SPlatten
          wrote on last edited by SPlatten
          #22

          @JonB , what diagram are you referring to? the fixed height is just a setting, the parent of the QScrollArea is the widget its under.

          Kind Regards,
          Sy

          JonBJ 1 Reply Last reply
          0
          • SPlattenS SPlatten

            @JonB , what diagram are you referring to? the fixed height is just a setting, the parent of the QScrollArea is the widget its under.

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

            @SPlatten said in QGroupBox, QScrollArea, QFormLayout:

            what diagram are you referring to?

            The 3 lines I quoted verbatim from your previous post. Whatever.

            SPlattenS 1 Reply Last reply
            0
            • JonBJ JonB

              @SPlatten said in QGroupBox, QScrollArea, QFormLayout:

              what diagram are you referring to?

              The 3 lines I quoted verbatim from your previous post. Whatever.

              SPlattenS Offline
              SPlattenS Offline
              SPlatten
              wrote on last edited by
              #24

              @JonB , yes and...haven't I explained what it means ?

              Kind Regards,
              Sy

              JonBJ 1 Reply Last reply
              0
              • SPlattenS SPlatten

                @JonB , yes and...haven't I explained what it means ?

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

                @SPlatten
                In @SGaist's "diagram" QFormLayout is descended (via a QWidget) from QScrollArea. In yours they are siblings, and then you say "Where only the QFormLayout is scrollable, but it isn't." If you think your diagram is clear and what you mean that's up to you.

                SPlattenS 1 Reply Last reply
                0
                • JonBJ JonB

                  @SPlatten
                  In @SGaist's "diagram" QFormLayout is descended (via a QWidget) from QScrollArea. In yours they are siblings, and then you say "Where only the QFormLayout is scrollable, but it isn't." If you think your diagram is clear and what you mean that's up to you.

                  SPlattenS Offline
                  SPlattenS Offline
                  SPlatten
                  wrote on last edited by SPlatten
                  #26

                  @JonB

                  //Create container for errors panel
                          mpobjErrors = new QWidget(this);
                          mpvbloErrors = new QVBoxLayout;
                          mpobjErrors->setLayout(mpvbloErrors);
                          mpsaErrors = new QScrollArea;
                          int intFixedHeight(fontMetrics().height() * MainWindow::mscuintErrorRows);
                          mpsaErrors->setFixedHeight(intFixedHeight);
                      //Create a widget that contains the scrollable errors form
                          QWidget* pobjFormErrorsContr(new QWidget);
                          mpsaErrors->setWidget(pobjFormErrorsContr);
                          mpfrmloErrors = new QFormLayout;
                          pobjFormErrorsContr->setLayout(mpfrmloErrors);
                          mpvbloErrors->addWidget(pobjFormErrorsContr, 1, Qt::AlignHCenter);
                      //Create a push button for acknowledging and clearing errors panel
                          QPushButton* pbtnAck(new QPushButton(tr("&Clear Errors")));
                          mpvbloErrors->addWidget(pbtnAck, 1, Qt::AlignHCenter);
                          QObject::connect(pbtnAck, &QPushButton::clicked,
                              [this, pbtnAck]
                              {
                                  mpobjErrors->setVisible(false);
                              }
                          );
                      //Default to hidden until errors are available to display
                          mpobjErrors->setVisible(false);
                  

                  From the above the structure should be:

                  QWidget
                  -- QVBoxLayout
                  ----- QScrollArea, with fixed height to show 3 rows
                  ------- QWidget
                  ---------- QFormLayout
                  ------ QPushButton

                  The image of this output:
                  988009f8-981b-407c-bb8e-2b71fe94befd-image.png
                  The form layout needs to be the full width of the QVBoxLayout and should be just 3 rows as the image shows it isn't.

                  Kind Regards,
                  Sy

                  JonBJ 1 Reply Last reply
                  0
                  • SPlattenS SPlatten

                    @JonB

                    //Create container for errors panel
                            mpobjErrors = new QWidget(this);
                            mpvbloErrors = new QVBoxLayout;
                            mpobjErrors->setLayout(mpvbloErrors);
                            mpsaErrors = new QScrollArea;
                            int intFixedHeight(fontMetrics().height() * MainWindow::mscuintErrorRows);
                            mpsaErrors->setFixedHeight(intFixedHeight);
                        //Create a widget that contains the scrollable errors form
                            QWidget* pobjFormErrorsContr(new QWidget);
                            mpsaErrors->setWidget(pobjFormErrorsContr);
                            mpfrmloErrors = new QFormLayout;
                            pobjFormErrorsContr->setLayout(mpfrmloErrors);
                            mpvbloErrors->addWidget(pobjFormErrorsContr, 1, Qt::AlignHCenter);
                        //Create a push button for acknowledging and clearing errors panel
                            QPushButton* pbtnAck(new QPushButton(tr("&Clear Errors")));
                            mpvbloErrors->addWidget(pbtnAck, 1, Qt::AlignHCenter);
                            QObject::connect(pbtnAck, &QPushButton::clicked,
                                [this, pbtnAck]
                                {
                                    mpobjErrors->setVisible(false);
                                }
                            );
                        //Default to hidden until errors are available to display
                            mpobjErrors->setVisible(false);
                    

                    From the above the structure should be:

                    QWidget
                    -- QVBoxLayout
                    ----- QScrollArea, with fixed height to show 3 rows
                    ------- QWidget
                    ---------- QFormLayout
                    ------ QPushButton

                    The image of this output:
                    988009f8-981b-407c-bb8e-2b71fe94befd-image.png
                    The form layout needs to be the full width of the QVBoxLayout and should be just 3 rows as the image shows it isn't.

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

                    @SPlatten
                    Your "diagram" now looks like @SGaist's, so I am happy.

                    I have played with scroll areas all morning for you, and I have had enough! Play with this:

                    #include "widget.h"
                    
                    #include <QApplication>
                    #include <QScrollArea>
                    #include <QBoxLayout>
                    #include <QPushButton>
                    
                    int main(int argc, char *argv[])
                    {
                        QApplication a(argc, argv);
                        Widget w;
                    
                        QVBoxLayout layout0;
                        w.setLayout(&layout0);
                    
                        QScrollArea scrollArea(&w);
                        layout0.addWidget(&scrollArea);
                        QWidget container(&scrollArea);
                        scrollArea.setWidget(&container);
                        QVBoxLayout layout;
                        container.setLayout(&layout);
                        for (int i = 0; i < 10; i++)
                            layout.addWidget(new QPushButton);
                    
                        scrollArea.setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded);
                        scrollArea.setFixedHeight(100);
                        scrollArea.setWidgetResizable(true);
                    
                        w.show();
                        return a.exec();
                    }
                    

                    Note the scrollArea.setWidgetResizable(true);. Without that I don't actually see any buttons. Is that what you are missing?

                    Don't ask me about Qt layouts/size policies etc., I have always found them about as intuitive as a duck-billed platypus, I play till I get what I want.

                    SPlattenS 1 Reply Last reply
                    0
                    • JonBJ JonB

                      @SPlatten
                      Your "diagram" now looks like @SGaist's, so I am happy.

                      I have played with scroll areas all morning for you, and I have had enough! Play with this:

                      #include "widget.h"
                      
                      #include <QApplication>
                      #include <QScrollArea>
                      #include <QBoxLayout>
                      #include <QPushButton>
                      
                      int main(int argc, char *argv[])
                      {
                          QApplication a(argc, argv);
                          Widget w;
                      
                          QVBoxLayout layout0;
                          w.setLayout(&layout0);
                      
                          QScrollArea scrollArea(&w);
                          layout0.addWidget(&scrollArea);
                          QWidget container(&scrollArea);
                          scrollArea.setWidget(&container);
                          QVBoxLayout layout;
                          container.setLayout(&layout);
                          for (int i = 0; i < 10; i++)
                              layout.addWidget(new QPushButton);
                      
                          scrollArea.setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded);
                          scrollArea.setFixedHeight(100);
                          scrollArea.setWidgetResizable(true);
                      
                          w.show();
                          return a.exec();
                      }
                      

                      Note the scrollArea.setWidgetResizable(true);. Without that I don't actually see any buttons. Is that what you are missing?

                      Don't ask me about Qt layouts/size policies etc., I have always found them about as intuitive as a duck-billed platypus, I play till I get what I want.

                      SPlattenS Offline
                      SPlattenS Offline
                      SPlatten
                      wrote on last edited by SPlatten
                      #28

                      @JonB , thank you, however its missing the QFormLayout which is required, see my post before you post.

                      Edited code, still doesn't work.

                          //Create container for errors panel
                              mpobjErrors = new QWidget(this);
                              mpvbloErrors = new QVBoxLayout;
                              mpobjErrors->setLayout(mpvbloErrors);
                          //Create scroll area
                              mpsaErrors = new QScrollArea(mpobjErrors);
                          //Create a widget that contains the scrollable errors form
                              QWidget* pobjFormErrorsContr(new QWidget(mpsaErrors));
                          //Set-up scroll area
                              mpsaErrors->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
                              int intFixedHeight(fontMetrics().height() * MainWindow::mscuintErrorRows);
                              mpsaErrors->setWidget(pobjFormErrorsContr);
                              mpsaErrors->setFixedHeight(intFixedHeight);
                              mpsaErrors->setWidgetResizable(true);
                              mpfrmloErrors = new QFormLayout(pobjFormErrorsContr);
                              mpvbloErrors->addWidget(pobjFormErrorsContr, 1, Qt::AlignHCenter);//addLayout(mpfrmloErrors, 1);//
                          //Create a push button for acknowledging and clearing errors panel
                              QPushButton* pbtnAck(new QPushButton(tr("&Clear Errors")));
                              mpvbloErrors->addWidget(pbtnAck, 1, Qt::AlignHCenter);
                              QObject::connect(pbtnAck, &QPushButton::clicked,
                                  [this, pbtnAck]
                                  {
                                      mpobjErrors->setVisible(false);
                                  }
                              );
                      

                      Kind Regards,
                      Sy

                      JonBJ 1 Reply Last reply
                      0
                      • SPlattenS SPlatten

                        @JonB , thank you, however its missing the QFormLayout which is required, see my post before you post.

                        Edited code, still doesn't work.

                            //Create container for errors panel
                                mpobjErrors = new QWidget(this);
                                mpvbloErrors = new QVBoxLayout;
                                mpobjErrors->setLayout(mpvbloErrors);
                            //Create scroll area
                                mpsaErrors = new QScrollArea(mpobjErrors);
                            //Create a widget that contains the scrollable errors form
                                QWidget* pobjFormErrorsContr(new QWidget(mpsaErrors));
                            //Set-up scroll area
                                mpsaErrors->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
                                int intFixedHeight(fontMetrics().height() * MainWindow::mscuintErrorRows);
                                mpsaErrors->setWidget(pobjFormErrorsContr);
                                mpsaErrors->setFixedHeight(intFixedHeight);
                                mpsaErrors->setWidgetResizable(true);
                                mpfrmloErrors = new QFormLayout(pobjFormErrorsContr);
                                mpvbloErrors->addWidget(pobjFormErrorsContr, 1, Qt::AlignHCenter);//addLayout(mpfrmloErrors, 1);//
                            //Create a push button for acknowledging and clearing errors panel
                                QPushButton* pbtnAck(new QPushButton(tr("&Clear Errors")));
                                mpvbloErrors->addWidget(pbtnAck, 1, Qt::AlignHCenter);
                                QObject::connect(pbtnAck, &QPushButton::clicked,
                                    [this, pbtnAck]
                                    {
                                        mpobjErrors->setVisible(false);
                                    }
                                );
                        
                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by
                        #29

                        @SPlatten
                        I found I had to put in scrollArea.setWidgetResizable(true); to make it respect the height. You are saying it still does not. I assume you have verified the value for fontMetrics().height() * MainWindow::mscuintErrorRows. You can put a QFormLayout into my sample code in place of QVBoxLayout layout;, I can't see why that would behave any differently vertically.

                        SPlattenS 1 Reply Last reply
                        0
                        • JonBJ JonB

                          @SPlatten
                          I found I had to put in scrollArea.setWidgetResizable(true); to make it respect the height. You are saying it still does not. I assume you have verified the value for fontMetrics().height() * MainWindow::mscuintErrorRows. You can put a QFormLayout into my sample code in place of QVBoxLayout layout;, I can't see why that would behave any differently vertically.

                          SPlattenS Offline
                          SPlattenS Offline
                          SPlatten
                          wrote on last edited by SPlatten
                          #30

                          @JonB , just to verify:

                          int intFontHeight(fontMetrics().height()),
                              intFixedHeight(intFontHeight * MainWindow::mscuintErrorRows);
                          

                          intFontHeight is 13
                          MainWindow::mscuintErrorRows is 3
                          intFixedHeight is 39

                          Clearly setFixedHeight on mpsaErrors is not having the desired effect.

                          Kind Regards,
                          Sy

                          1 Reply Last reply
                          0
                          • M Offline
                            M Offline
                            mpergand
                            wrote on last edited by mpergand
                            #31

                            Assuming margins at set to zero:

                            pFormLayout=new QFormLayout;
                            pFormLayout->setContentsMargins(0,0,0,0);
                            pFormLayout->setSpacing(0);
                            pFormLayout->setHorizontalSpacing(10);
                            

                            In the show event you can calculate 3 rows height like that:

                            void Widget::showEvent(QShowEvent* event)
                            {
                                QWidget::showEvent(event);
                                QLayoutItem * item=pFormLayout-> itemAt(0);
                                int h=item->geometry().height();
                            
                                pScrollArea->setFixedHeight(h*3+2);
                            
                            }
                            

                            SPlattenS 1 Reply Last reply
                            2
                            • M mpergand

                              Assuming margins at set to zero:

                              pFormLayout=new QFormLayout;
                              pFormLayout->setContentsMargins(0,0,0,0);
                              pFormLayout->setSpacing(0);
                              pFormLayout->setHorizontalSpacing(10);
                              

                              In the show event you can calculate 3 rows height like that:

                              void Widget::showEvent(QShowEvent* event)
                              {
                                  QWidget::showEvent(event);
                                  QLayoutItem * item=pFormLayout-> itemAt(0);
                                  int h=item->geometry().height();
                              
                                  pScrollArea->setFixedHeight(h*3+2);
                              
                              }
                              

                              SPlattenS Offline
                              SPlattenS Offline
                              SPlatten
                              wrote on last edited by
                              #32

                              @mpergand , thank you

                              Kind Regards,
                              Sy

                              M 1 Reply Last reply
                              0
                              • SPlattenS SPlatten

                                @mpergand , thank you

                                M Offline
                                M Offline
                                mpergand
                                wrote on last edited by mpergand
                                #33

                                @SPlatten
                                I assumed that the formLayout is not empty, unless the app will crash.

                                If you create one row in the constructor and want an empty form on show up, you can do:

                                QWidget::showEvent(event);
                                QLayoutItem* item=pFormLayout-> itemAt(0);
                                int h=item->geometry().height();
                                pScrollArea->setFixedHeight(h3+3);
                                pFormLayout->removeRow(0);

                                [WARNING]
                                Multi showEvent can occur, you need to add some flag to prevent that:

                                void Widget::showEvent(QShowEvent* event)
                                {
                                    static bool firstShow=true;
                                
                                    QWidget::showEvent(event);
                                     
                                    if(firstShow)
                                        {
                                        QLayoutItem * item=pFormLayout-> itemAt(0);
                                        int h=item->geometry().height();
                                        pScrollArea->setFixedHeight(h*3+3);
                                        pFormLayout->removeRow(0);
                                        firstShow=false;
                                        }
                                }
                                
                                SPlattenS 2 Replies Last reply
                                0
                                • M mpergand

                                  @SPlatten
                                  I assumed that the formLayout is not empty, unless the app will crash.

                                  If you create one row in the constructor and want an empty form on show up, you can do:

                                  QWidget::showEvent(event);
                                  QLayoutItem* item=pFormLayout-> itemAt(0);
                                  int h=item->geometry().height();
                                  pScrollArea->setFixedHeight(h3+3);
                                  pFormLayout->removeRow(0);

                                  [WARNING]
                                  Multi showEvent can occur, you need to add some flag to prevent that:

                                  void Widget::showEvent(QShowEvent* event)
                                  {
                                      static bool firstShow=true;
                                  
                                      QWidget::showEvent(event);
                                       
                                      if(firstShow)
                                          {
                                          QLayoutItem * item=pFormLayout-> itemAt(0);
                                          int h=item->geometry().height();
                                          pScrollArea->setFixedHeight(h*3+3);
                                          pFormLayout->removeRow(0);
                                          firstShow=false;
                                          }
                                  }
                                  
                                  SPlattenS Offline
                                  SPlattenS Offline
                                  SPlatten
                                  wrote on last edited by
                                  #34

                                  @mpergand , this layout will only be displayed if there is content to display.

                                  Kind Regards,
                                  Sy

                                  JoeCFDJ 1 Reply Last reply
                                  0
                                  • SPlattenS SPlatten

                                    @mpergand , this layout will only be displayed if there is content to display.

                                    JoeCFDJ Offline
                                    JoeCFDJ Offline
                                    JoeCFD
                                    wrote on last edited by JoeCFD
                                    #35

                                    @SPlatten Q
                                    When you use font size to set item height, it is better to use some reference chars. That is what I do:
                                    Rect bounding_rect = QFontMetrics( font ).tightBoundingRect( QString( "MWLPGHXYZmwlpghxyz" ) );
                                    use bounding_rect.height();
                                    And item height has to be a bit bigger than this height.

                                    1 Reply Last reply
                                    1
                                    • M mpergand

                                      @SPlatten
                                      I assumed that the formLayout is not empty, unless the app will crash.

                                      If you create one row in the constructor and want an empty form on show up, you can do:

                                      QWidget::showEvent(event);
                                      QLayoutItem* item=pFormLayout-> itemAt(0);
                                      int h=item->geometry().height();
                                      pScrollArea->setFixedHeight(h3+3);
                                      pFormLayout->removeRow(0);

                                      [WARNING]
                                      Multi showEvent can occur, you need to add some flag to prevent that:

                                      void Widget::showEvent(QShowEvent* event)
                                      {
                                          static bool firstShow=true;
                                      
                                          QWidget::showEvent(event);
                                           
                                          if(firstShow)
                                              {
                                              QLayoutItem * item=pFormLayout-> itemAt(0);
                                              int h=item->geometry().height();
                                              pScrollArea->setFixedHeight(h*3+3);
                                              pFormLayout->removeRow(0);
                                              firstShow=false;
                                              }
                                      }
                                      
                                      SPlattenS Offline
                                      SPlattenS Offline
                                      SPlatten
                                      wrote on last edited by SPlatten
                                      #36

                                      @mpergand , how is the showEvent connected and to which widget? I assume this is the MainWindow instance that this code is relevant to?

                                      Kind Regards,
                                      Sy

                                      M 1 Reply Last reply
                                      0
                                      • SPlattenS SPlatten

                                        @mpergand , how is the showEvent connected and to which widget? I assume this is the MainWindow instance that this code is relevant to?

                                        M Offline
                                        M Offline
                                        mpergand
                                        wrote on last edited by
                                        #37

                                        @SPlatten
                                        Here Widget is the top level object, but it does not have to be.

                                        how is the showEvent connected

                                        It's connected to nothing, it's a virtual method of QWidget.

                                        SPlattenS 1 Reply Last reply
                                        0
                                        • M mpergand

                                          @SPlatten
                                          Here Widget is the top level object, but it does not have to be.

                                          how is the showEvent connected

                                          It's connected to nothing, it's a virtual method of QWidget.

                                          SPlattenS Offline
                                          SPlattenS Offline
                                          SPlatten
                                          wrote on last edited by
                                          #38

                                          @mpergand, can you post your full example source, showing the relationship between pScrollArea and pFormLayout ?

                                          Thank you,

                                          Kind Regards,
                                          Sy

                                          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