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. Change QGroupBox Layout more than once
Forum Updated to NodeBB v4.3 + New Features

Change QGroupBox Layout more than once

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 3 Posters 1.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Z Offline
    Z Offline
    Zero_emc
    wrote on last edited by
    #1

    So in my code I have a QGroupBox that I create in the QtCreator as shown below:
    315d19db-5182-4bb2-9783-682f400e742d-image.png

    What I need is to create radiobuttons inside of it, but it depends on the numbers of buttons saved in my class (l_Questoes is a list of objects of my class), so it need to be generic, and what i'm trying to do is basically this:

    QVBoxLayout *vbox = new QVBoxLayout();
    for (int i = 0; i < static_cast<question_mult*>(l_Questoes[ui->l_prova->row(current)])->alternativas.size(); i++) {
    QRadioButton *button = new QradioButton(static_cast<question_mult*>l_Questoes[ui->l_prova->row(current)])->alternativas[i]);
    vbox->addWidget(button);
    ui->g_alternativas->setLayout(vbox);
    

    I'm creating a layout, adding all the buttons and making my QGroupBox (ui->g_alternativas) get this layout. But I'm receiving this error message:
    QWidget::setLayout: Attempting to set QLayout "" on QGroupBox "g_alternativas", which already has a layout
    Is there a way to break this layout before setting it, or I need to do this in other way?

    JonBJ 2 Replies Last reply
    0
    • Z Zero_emc

      So in my code I have a QGroupBox that I create in the QtCreator as shown below:
      315d19db-5182-4bb2-9783-682f400e742d-image.png

      What I need is to create radiobuttons inside of it, but it depends on the numbers of buttons saved in my class (l_Questoes is a list of objects of my class), so it need to be generic, and what i'm trying to do is basically this:

      QVBoxLayout *vbox = new QVBoxLayout();
      for (int i = 0; i < static_cast<question_mult*>(l_Questoes[ui->l_prova->row(current)])->alternativas.size(); i++) {
      QRadioButton *button = new QradioButton(static_cast<question_mult*>l_Questoes[ui->l_prova->row(current)])->alternativas[i]);
      vbox->addWidget(button);
      ui->g_alternativas->setLayout(vbox);
      

      I'm creating a layout, adding all the buttons and making my QGroupBox (ui->g_alternativas) get this layout. But I'm receiving this error message:
      QWidget::setLayout: Attempting to set QLayout "" on QGroupBox "g_alternativas", which already has a layout
      Is there a way to break this layout before setting it, or I need to do this in other way?

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

      @Zero_emc
      Read the docs https://doc.qt.io/qt-5/qwidget.html#setLayout

      If there already is a layout manager installed on this widget, QWidget won't let you install another. You must first delete the existing layout manager (returned by layout()) before you can call setLayout() with the new layout.

      1 Reply Last reply
      1
      • B Offline
        B Offline
        Bonnie
        wrote on last edited by Bonnie
        #3

        Since you are always using a same type of layout, you can keep that layout, but remove all the child widgets, delete them.

        QLayout *layout = ui->g_alternativas->layout();
        QLayoutItem *child;
        while ((child = layout->takeAt(0)) != 0) {
            delete child->widget();
            delete child;
        }
        

        Then add new ones to it.

        1 Reply Last reply
        2
        • Z Zero_emc

          So in my code I have a QGroupBox that I create in the QtCreator as shown below:
          315d19db-5182-4bb2-9783-682f400e742d-image.png

          What I need is to create radiobuttons inside of it, but it depends on the numbers of buttons saved in my class (l_Questoes is a list of objects of my class), so it need to be generic, and what i'm trying to do is basically this:

          QVBoxLayout *vbox = new QVBoxLayout();
          for (int i = 0; i < static_cast<question_mult*>(l_Questoes[ui->l_prova->row(current)])->alternativas.size(); i++) {
          QRadioButton *button = new QradioButton(static_cast<question_mult*>l_Questoes[ui->l_prova->row(current)])->alternativas[i]);
          vbox->addWidget(button);
          ui->g_alternativas->setLayout(vbox);
          

          I'm creating a layout, adding all the buttons and making my QGroupBox (ui->g_alternativas) get this layout. But I'm receiving this error message:
          QWidget::setLayout: Attempting to set QLayout "" on QGroupBox "g_alternativas", which already has a layout
          Is there a way to break this layout before setting it, or I need to do this in other way?

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

          @Zero_emc
          If you do it @Bonnie's way, which is good to retain an existing layout, if you have put more onto the layout than just the widgets I use generically:

              QLayoutItem *wItem;
              while ((wItem = layout.takeAt(0)) != nullptr)
              {
                  delete wItem->widget();
                  delete wItem->layout();
                  delete wItem->spacerItem();
                  delete wItem;
              }
          

          EDIT See @Bonnie's reply below. I can't delete this now, but I'd respect his answer more then mine!

          B 1 Reply Last reply
          1
          • JonBJ JonB

            @Zero_emc
            If you do it @Bonnie's way, which is good to retain an existing layout, if you have put more onto the layout than just the widgets I use generically:

                QLayoutItem *wItem;
                while ((wItem = layout.takeAt(0)) != nullptr)
                {
                    delete wItem->widget();
                    delete wItem->layout();
                    delete wItem->spacerItem();
                    delete wItem;
                }
            

            EDIT See @Bonnie's reply below. I can't delete this now, but I'd respect his answer more then mine!

            B Offline
            B Offline
            Bonnie
            wrote on last edited by Bonnie
            #5

            @JonB Hey, I was also thinking about that.
            But I've checked the source code.

            QLayout * QLayout::layout()
            {
                return this;
            }
            
            QSpacerItem * QSpacerItem::spacerItem()
            {
                return this;
            }
            

            And also in the doc:

            [virtual] QWidget *QLayoutItem::widget()
            If this item manages a QWidget, returns that widget. Otherwise, nullptr is returned.
            Note: While the functions layout() and spacerItem() perform casts, this function returns another object: QLayout and QSpacerItem inherit QLayoutItem, while QWidget does not.

            Those make think that there's no need to delete layout() and spacerItem().
            What do you think?

            [ADDED]
            P.S.But if the child item is a sub-layout, there should be extra code to delete its child items recurringly.

            JonBJ 1 Reply Last reply
            2
            • B Bonnie

              @JonB Hey, I was also thinking about that.
              But I've checked the source code.

              QLayout * QLayout::layout()
              {
                  return this;
              }
              
              QSpacerItem * QSpacerItem::spacerItem()
              {
                  return this;
              }
              

              And also in the doc:

              [virtual] QWidget *QLayoutItem::widget()
              If this item manages a QWidget, returns that widget. Otherwise, nullptr is returned.
              Note: While the functions layout() and spacerItem() perform casts, this function returns another object: QLayout and QSpacerItem inherit QLayoutItem, while QWidget does not.

              Those make think that there's no need to delete layout() and spacerItem().
              What do you think?

              [ADDED]
              P.S.But if the child item is a sub-layout, there should be extra code to delete its child items recurringly.

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

              @Bonnie
              I'm going to take the 5th on this ;-) My layouts don't actually have spacers or sub-layouts etc. so I never tested that part of the code, I just assumed.... And I didn't bother with recursion because I knew I didn't have any.

              There seems to be a host of suggestions for doing this properly, e.g. https://stackoverflow.com/questions/4857188/clearing-a-layout-in-qt with several different opinions.

              Since I trust you more than myself in this area, I'm actually going to go change my own code to yours since I didn't test all routes in mine! And I'll mark my earlier post with a disclaimer :)

              Z 1 Reply Last reply
              1
              • JonBJ JonB

                @Bonnie
                I'm going to take the 5th on this ;-) My layouts don't actually have spacers or sub-layouts etc. so I never tested that part of the code, I just assumed.... And I didn't bother with recursion because I knew I didn't have any.

                There seems to be a host of suggestions for doing this properly, e.g. https://stackoverflow.com/questions/4857188/clearing-a-layout-in-qt with several different opinions.

                Since I trust you more than myself in this area, I'm actually going to go change my own code to yours since I didn't test all routes in mine! And I'll mark my earlier post with a disclaimer :)

                Z Offline
                Z Offline
                Zero_emc
                wrote on last edited by
                #7

                @JonB @Bonnie Guys, thank you so much for the answers, now i'm actually questioning if i'm doing it right, I'm still a bit confused about using the Qt Creator to do everything or doing it by code. I think doing it by the Qt Creator i'm chaining all my code to the interface, and it's harder to make it generic. I'll try to understand more everything you guys said and try to adapt my code, thank you!

                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