跳到內容
  • 版面
  • 最新
  • 標籤
  • 熱門
  • 使用者
  • 群組
  • 搜尋
  • Get Qt Extensions
  • Unsolved
Collapse
品牌標誌
  1. 首頁
  2. Qt Development
  3. General and Desktop
  4. QGroupBox, QScrollArea, QFormLayout
Forum Updated to NodeBB v4.3 + New Features

QGroupBox, QScrollArea, QFormLayout

已排程 已置頂 已鎖定 已移動 Solved General and Desktop
41 貼文 7 Posters 7.3k 瀏覽 4 Watching
  • 從舊到新
  • 從新到舊
  • 最多點贊
回覆
  • 在新貼文中回覆
登入後回覆
此主題已被刪除。只有擁有主題管理權限的使用者可以查看。
  • SPlattenS 離線
    SPlattenS 離線
    SPlatten
    寫於 最後由 編輯
    #1

    I am trying to create a scrollable area that will contain two columns, I'm not sure of the correct way to do this, so far:

    pgrpErrors = new QGroupBox(this);
    QScrollArea* psaErrors(new QScrollArea(pgrpErrors));
    QFormLayout* pfrmloErrors(new QFormLayout);
    psaErrors->setLayout(pfrmloErrors);
    

    Later in the project I want to get the form so I can add content to it:

    QFormLayout* pfrmloErrors(qobject_cast<QFormLayout*>(pgrpErrors->layout()));
    

    From the above pfrmloErrors is 0x0. What I want to do is create a form with 2 rows visible and a scrollable container that shows just these 2 rows and the rest can be accessed by scrolling.

    Kind Regards,
    Sy

    JonBJ 1 條回覆 最後回覆
    0
    • M 離線
      M 離線
      mpergand
      寫於 最後由 mpergand 編輯
      #39

      Widget.h

      #include <QWidget>
      
      class QScrollArea;
      class QFormLayout;
      
      class Widget : public QWidget
          {
              Q_OBJECT
              
          public:
              
                      explicit Widget(QWidget *parent = nullptr);
                      
          private:
                            void  showEvent(QShowEvent* event);
                     QScrollArea* pScrollArea;
                     QFormLayout* pFormLayout;
      };
      

      Widget.cpp

      Widget::Widget(QWidget *parent) : QWidget(parent)
      {
          auto vLayout=new QVBoxLayout;
          setLayout(vLayout);
          
          pScrollArea=new QScrollArea;
          vLayout->addWidget(pScrollArea);
          
          auto sWidget=new QWidget;
          pScrollArea->setWidget(sWidget);
          pScrollArea->setWidgetResizable(true);
         
          pFormLayout=new QFormLayout;
          pFormLayout->setContentsMargins(0,0,0,1);
          pFormLayout->setSpacing(0);
          pFormLayout->setHorizontalSpacing(10);
          sWidget->setLayout(pFormLayout);
      
          // add one row for calculation in showEvent
          pFormLayout->addRow("", new QLabel());  
      
          vLayout->addWidget(new QPushButton("Clear"));
      }
      
      SPlattenS 2 條回覆 最後回覆
      0
      • M 離線
        M 離線
        mchinand
        寫於 最後由 編輯
        #2

        @SPlatten said in QGroupBox, QScrollArea, QFormLayout:

        Later in the project I want to get the form so I can add content to it:
        QFormLayout* pfrmloErrors(qobject_cast<QFormLayout*>(pgrpErrors->layout()));

        Shouldn't this be:
        QFormLayout* pfrmloErrors = qobject_cast<QFormLayout*>(pgrpErrors->layout());

        SPlattenS 1 條回覆 最後回覆
        0
        • M mchinand

          @SPlatten said in QGroupBox, QScrollArea, QFormLayout:

          Later in the project I want to get the form so I can add content to it:
          QFormLayout* pfrmloErrors(qobject_cast<QFormLayout*>(pgrpErrors->layout()));

          Shouldn't this be:
          QFormLayout* pfrmloErrors = qobject_cast<QFormLayout*>(pgrpErrors->layout());

          SPlattenS 離線
          SPlattenS 離線
          SPlatten
          寫於 最後由 SPlatten 編輯
          #3

          @mchinand , I really don't know, should it?

          I've modified the code to:

          psaErrors = new QScrollArea(this);
          pgrpErrors = new QGroupBox(this);
          QFormLayout* pfrmloErrors(new QFormLayout);
          pgrpErrors->setLayout(pfrmloErrors);
          psaErrors->setWidget(pgrpErrors);
          

          A box appears but no content displayed.

          Kind Regards,
          Sy

          1 條回覆 最後回覆
          0
          • SPlattenS SPlatten

            I am trying to create a scrollable area that will contain two columns, I'm not sure of the correct way to do this, so far:

            pgrpErrors = new QGroupBox(this);
            QScrollArea* psaErrors(new QScrollArea(pgrpErrors));
            QFormLayout* pfrmloErrors(new QFormLayout);
            psaErrors->setLayout(pfrmloErrors);
            

            Later in the project I want to get the form so I can add content to it:

            QFormLayout* pfrmloErrors(qobject_cast<QFormLayout*>(pgrpErrors->layout()));
            

            From the above pfrmloErrors is 0x0. What I want to do is create a form with 2 rows visible and a scrollable container that shows just these 2 rows and the rest can be accessed by scrolling.

            JonBJ 離線
            JonBJ 離線
            JonB
            寫於 最後由 編輯
            #4

            @SPlatten
            The QFormLayout is on psaErrors (QScrollArea*). So why do you try to obtain it from pgrpErrors (QGroupBox*)?

            SPlattenS 1 條回覆 最後回覆
            0
            • M 離線
              M 離線
              mchinand
              寫於 最後由 mchinand 編輯
              #5

              Yes, if you're just getting a reference to the existing layout (see @JonB 's comment on whether that's the correct layout that you want).

              1 條回覆 最後回覆
              0
              • JonBJ JonB

                @SPlatten
                The QFormLayout is on psaErrors (QScrollArea*). So why do you try to obtain it from pgrpErrors (QGroupBox*)?

                SPlattenS 離線
                SPlattenS 離線
                SPlatten
                寫於 最後由 編輯
                #6

                @JonB See post I made whilst you posted yours...

                Kind Regards,
                Sy

                JonBJ 1 條回覆 最後回覆
                0
                • SPlattenS SPlatten

                  @JonB See post I made whilst you posted yours...

                  JonBJ 離線
                  JonBJ 離線
                  JonB
                  寫於 最後由 編輯
                  #7

                  @SPlatten
                  I could easily be wrong, so don't push me too much, but both QScrollArea and QGroupBox are containers, I thought you add widgets to these but not layouts? Maybe first design this in Designer so it looks like what you want, and then look at the code that generates? Or, ignore this if my post is off-target.

                  SPlattenS 1 條回覆 最後回覆
                  0
                  • JonBJ JonB

                    @SPlatten
                    I could easily be wrong, so don't push me too much, but both QScrollArea and QGroupBox are containers, I thought you add widgets to these but not layouts? Maybe first design this in Designer so it looks like what you want, and then look at the code that generates? Or, ignore this if my post is off-target.

                    SPlattenS 離線
                    SPlattenS 離線
                    SPlatten
                    寫於 最後由 編輯
                    #8

                    @JonB , thank you, I will have a go in Qt Creator.

                    Kind Regards,
                    Sy

                    SPlattenS 1 條回覆 最後回覆
                    0
                    • SPlattenS SPlatten

                      @JonB , thank you, I will have a go in Qt Creator.

                      SPlattenS 離線
                      SPlattenS 離線
                      SPlatten
                      寫於 最後由 SPlatten 編輯
                      #9

                      @JonB , @mchinand , a little better...

                      psaErrors = new QScrollArea(this);
                      pfrmloErrors = new QFormLayout;
                      psaErrors->setLayout(pfrmloErrors);
                      

                      This works now, however its still not quite right...if the number of rows in the form is greater than 4 then the row height of each item is squashed, whats happening?

                      The QScrollArea widget doesn't appear around the content that can be scrolled, the QScrollArea appears top left on the display, very small, is this a default, do I have to set the geometry of the QScrollArea manually?

                      Also, how do I set the maximum height of the scrollable area?

                      Kind Regards,
                      Sy

                      JonBJ 1 條回覆 最後回覆
                      0
                      • SPlattenS SPlatten

                        @JonB , @mchinand , a little better...

                        psaErrors = new QScrollArea(this);
                        pfrmloErrors = new QFormLayout;
                        psaErrors->setLayout(pfrmloErrors);
                        

                        This works now, however its still not quite right...if the number of rows in the form is greater than 4 then the row height of each item is squashed, whats happening?

                        The QScrollArea widget doesn't appear around the content that can be scrolled, the QScrollArea appears top left on the display, very small, is this a default, do I have to set the geometry of the QScrollArea manually?

                        Also, how do I set the maximum height of the scrollable area?

                        JonBJ 離線
                        JonBJ 離線
                        JonB
                        寫於 最後由 JonB 編輯
                        #10

                        @SPlatten
                        Does not sound right. I am not the right person to ask about this, but....

                        ... That does not sound at all like I understood QScrollArea to work. Look at https://doc.qt.io/qt-5/qscrollarea.html#details and examples elsewhere. My understanding is:

                        QWidget *yourWidget;
                        // put whatever you like on your widget, set your `QFormLayout` there
                        QScrollArea *scrollArea;
                        scrollArea->setWidget(yourWidget);
                        
                        SPlattenS 1 條回覆 最後回覆
                        3
                        • JonBJ JonB

                          @SPlatten
                          Does not sound right. I am not the right person to ask about this, but....

                          ... That does not sound at all like I understood QScrollArea to work. Look at https://doc.qt.io/qt-5/qscrollarea.html#details and examples elsewhere. My understanding is:

                          QWidget *yourWidget;
                          // put whatever you like on your widget, set your `QFormLayout` there
                          QScrollArea *scrollArea;
                          scrollArea->setWidget(yourWidget);
                          
                          SPlattenS 離線
                          SPlattenS 離線
                          SPlatten
                          寫於 最後由 SPlatten 編輯
                          #11

                          @JonB , I think the problem is I want to scroll a QVBoxLayout which isn't a widget. Here is the code and a screenshot of the results:

                                  mpvbloErrors = new QVBoxLayout(this);
                                  QWidget* pobjErrorPadding(new QWidget(this));
                                  mpsaErrors = new QScrollArea(this);
                                  mpsaErrors->setWidget(pobjErrorPadding);
                                  mpfrmloErrors = new QFormLayout(pobjErrorPadding);
                                  mpvbloErrors->addWidget(pobjErrorPadding);
                                  pobjErrorPadding->setLayout(mpfrmloErrors);
                                  mpsaErrors->setFixedHeight(100); // Just a fiddle to see what happens
                                  QPushButton* pbtnAck(new QPushButton(tr("&Clear Errors")));
                                  QObject::connect(pbtnAck, &QPushButton::clicked,
                                      [this, pbtnAck, pobjErrorPadding]
                                      {
                                          pbtnAck->setVisible(false);
                                          pobjErrorPadding->setVisible(false);
                                      }
                                  );
                                  mpvbloErrors->addWidget(pbtnAck, 1);
                          

                          f599a53c-f27c-4567-ba17-a01a12b22ea7-image.png cid:ii_kvb2bvn50
                          The empty box at the top left is the scroll area and using the scroll bars does move the image under it. I also want to limit the height of the text rows under to say two rows and scroll vertically to the rest.

                          Kind Regards,
                          Sy

                          1 條回覆 最後回覆
                          0
                          • Christian EhrlicherC 離線
                            Christian EhrlicherC 離線
                            Christian Ehrlicher
                            Lifetime Qt Champion
                            寫於 最後由 編輯
                            #12

                            @SPlatten said in QGroupBox, QScrollArea, QFormLayout:

                                mpsaErrors->setWidget(pobjErrorPadding);
                            

                            ...

                                mpvbloErrors->addWidget(pobjErrorPadding);
                            

                            It's only doing what you ask for - pobjErrorPadding is a child of mpvbloErrors and not mpsaErrors after this.

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

                            SPlattenS 1 條回覆 最後回覆
                            0
                            • Christian EhrlicherC Christian Ehrlicher

                              @SPlatten said in QGroupBox, QScrollArea, QFormLayout:

                                  mpsaErrors->setWidget(pobjErrorPadding);
                              

                              ...

                                  mpvbloErrors->addWidget(pobjErrorPadding);
                              

                              It's only doing what you ask for - pobjErrorPadding is a child of mpvbloErrors and not mpsaErrors after this.

                              SPlattenS 離線
                              SPlattenS 離線
                              SPlatten
                              寫於 最後由 編輯
                              #13

                              @Christian-Ehrlicher , thank you, I will look again.

                              Kind Regards,
                              Sy

                              1 條回覆 最後回覆
                              0
                              • SPlattenS 離線
                                SPlattenS 離線
                                SPlatten
                                寫於 最後由 SPlatten 編輯
                                #14

                                More edits, still not right:

                                        mpvbloErrors = new QVBoxLayout(this);
                                        mpsaErrors = new QScrollArea;       
                                        mpvbloErrors->addWidget(mpsaErrors);
                                        mpfrmloErrors = new QFormLayout;
                                        mpvbloErrors->addItem(mpfrmloErrors);
                                        int intFixedHeight(fontMetrics().height() * MainWindow::mscuintErrorRows);
                                        mpsaErrors->setFixedHeight(intFixedHeight);
                                        QPushButton* pbtnAck(new QPushButton(tr("&Clear Errors")));
                                        QObject::connect(pbtnAck, &QPushButton::clicked,
                                            [this, pbtnAck]
                                            {
                                                mpsaErrors->setVisible(false);
                                                pbtnAck->setVisible(false);
                                            }
                                        );
                                        mpvbloErrors->addWidget(pbtnAck, 1);
                                        QWidget* pobjErrorWrapper(this);
                                        pobjErrorWrapper->setLayout(mpvbloErrors);
                                

                                e171a811-eb08-4fa5-b7d6-924c324c443e-image.png

                                Now there should be red rows shown, expecting 3 but nothing...

                                Kind Regards,
                                Sy

                                1 條回覆 最後回覆
                                0
                                • SGaistS 離線
                                  SGaistS 離線
                                  SGaist
                                  Lifetime Qt Champion
                                  寫於 最後由 編輯
                                  #15

                                  Hi,

                                  As @JonB already wrote, QScrollArea is a container widget so 99% of the time you do not set a layout on it. You are in these 99%.

                                  As already suggested, use a QWidget on which you apply the QFormLayout and set that widget on the QScrollArea.

                                  You will then have the result you expect.

                                  Interested in AI ? www.idiap.ch
                                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                  SPlattenS 1 條回覆 最後回覆
                                  1
                                  • SGaistS SGaist

                                    Hi,

                                    As @JonB already wrote, QScrollArea is a container widget so 99% of the time you do not set a layout on it. You are in these 99%.

                                    As already suggested, use a QWidget on which you apply the QFormLayout and set that widget on the QScrollArea.

                                    You will then have the result you expect.

                                    SPlattenS 離線
                                    SPlattenS 離線
                                    SPlatten
                                    寫於 最後由 SPlatten 編輯
                                    #16

                                    @SGaist , latest code:

                                            mpobjErrors = new QWidget(this);      //Wrapper/container for everything
                                            mpvbloErrors = new QVBoxLayout;       //Vertical layout for error messages
                                            mpsaErrors = new QScrollArea;         //Vertical layout to be scrollable
                                            mpsaErrors->setWidget(mpobjErrors);   //Add scroll area to container
                                            mpobjErrors->setLayout(mpvbloErrors); //Add vertical layout to container
                                            int intFixedHeight(fontMetrics().height() * MainWindow::mscuintErrorRows);
                                            mpsaErrors->setFixedHeight(intFixedHeight);  //Large enough for 3 rows of errors
                                            mpvbloErrors->addStretch(1);          
                                            QPushButton* pbtnAck(new QPushButton(tr("&Clear Errors")));
                                            QObject::connect(pbtnAck, &QPushButton::clicked,
                                                [this, pbtnAck]
                                                {
                                                    mpobjErrors->setVisible(false);
                                                }
                                            );
                                            mpfrmloErrors = new QFormLayout;       //Layout for errors, time and cause
                                            mpvbloErrors->addLayout(mpfrmloErrors, 1); //Add form to vertical layout
                                            mpvbloErrors->addWidget(pbtnAck, 1, Qt::AlignHCenter); //Add button to container
                                    

                                    The result from is:
                                    4c81d34f-b6ab-455f-aa1e-60122d1de022-image.png

                                    I only want 3 lines to be displayed and the rest to be accessed using the scroll bar, but there is no scroll bar.

                                    Its the QFormLayout that is used to display the error lines, the QVBoxLayout is used to contain the QFormLayout and the Clear Errors button at the bottom. I want the QFormLayout to be scrollable.

                                    [edit]...:

                                        //Create container for errors panel
                                            mpobjErrors = new QWidget(this);
                                            mpvbloErrors = new QVBoxLayout;
                                            mpobjErrors->setLayout(mpvbloErrors);
                                        //Create a widget that contains the scrollable errors form
                                            QWidget* pobjFormErrorsContr(new QWidget(mpobjErrors));
                                            mpfrmloErrors = new QFormLayout;
                                            pobjFormErrorsContr->setLayout(mpfrmloErrors);
                                            int intFixedHeight(fontMetrics().height() * MainWindow::mscuintErrorRows);
                                            mpsaErrors = new QScrollArea;
                                            mpsaErrors->setWidget(pobjFormErrorsContr);
                                            mpsaErrors->setFixedHeight(intFixedHeight);
                                            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);
                                    

                                    I thought perhaps an additional widget container would be required for the QFormLayout, didn't help.

                                    Kind Regards,
                                    Sy

                                    1 條回覆 最後回覆
                                    0
                                    • SGaistS 離線
                                      SGaistS 離線
                                      SGaist
                                      Lifetime Qt Champion
                                      寫於 最後由 編輯
                                      #17

                                      Why do you have a QVBoxLayou and a QFormLayout in mpobjErrors on the widget in your QScrollArea ?

                                      The logic would rather be

                                      -- QWidget ("this" in your sample code)
                                      --- QVBoxLayout
                                      ---- QScrollArea (fixed height)
                                      ----- QWidget
                                      ------ QFormLayout
                                      ------- Dynamic number of widgets
                                      ---- QPushButton -> clear button

                                      So you don't have to hunt for the clear button if you have lots of errors.

                                      Note that depending on how many errors there might be limiting to three lines may not be the best user experience.

                                      Interested in AI ? www.idiap.ch
                                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                      SPlattenS 1 條回覆 最後回覆
                                      2
                                      • SGaistS SGaist

                                        Why do you have a QVBoxLayou and a QFormLayout in mpobjErrors on the widget in your QScrollArea ?

                                        The logic would rather be

                                        -- QWidget ("this" in your sample code)
                                        --- QVBoxLayout
                                        ---- QScrollArea (fixed height)
                                        ----- QWidget
                                        ------ QFormLayout
                                        ------- Dynamic number of widgets
                                        ---- QPushButton -> clear button

                                        So you don't have to hunt for the clear button if you have lots of errors.

                                        Note that depending on how many errors there might be limiting to three lines may not be the best user experience.

                                        SPlattenS 離線
                                        SPlattenS 離線
                                        SPlatten
                                        寫於 最後由 編輯
                                        #18

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

                                        Kind Regards,
                                        Sy

                                        JonBJ 1 條回覆 最後回覆
                                        0
                                        • 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 離線
                                          JonBJ 離線
                                          JonB
                                          寫於 最後由 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 條回覆 最後回覆
                                          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 離線
                                            SPlattenS 離線
                                            SPlatten
                                            寫於 最後由 編輯
                                            #20

                                            @JonB , see code above:

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

                                            Kind Regards,
                                            Sy

                                            JonBJ 1 條回覆 最後回覆
                                            0

                                            • 登入

                                            • Login or register to search.
                                            • 第一個貼文
                                              最後的貼文
                                            0
                                            • 版面
                                            • 最新
                                            • 標籤
                                            • 熱門
                                            • 使用者
                                            • 群組
                                            • 搜尋
                                            • Get Qt Extensions
                                            • Unsolved