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. Why Layout is reparenting to the top most widget through addChildLayout?

Why Layout is reparenting to the top most widget through addChildLayout?

Scheduled Pinned Locked Moved Unsolved General and Desktop
layout
9 Posts 4 Posters 1.6k 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.
  • L Offline
    L Offline
    leonardoMB
    wrote on 13 Jun 2022, 03:27 last edited by leonardoMB
    #1

    Hi I have the following:

    QWidget *widget_1 = new QWidget(this);
    QGridLayout *layout_1 = new QGridLayout;
    widget_1->setLayout(layout_1);
    QGridLayout *layout_2 = new QGridLayout;
    layout_2->addWidget(_qButton, 0, 0, 1, 2, Qt::AlignHCenter);
    layout_1->addLayout(layout_2,0,1);
    

    So I would expect that layout_1 and _qButton are child of widget_1, meanwhile layout_2 should be child of layout_1.
    Here is why: addLayout call adoptLayout that calls
    addChildLayout(layout_2) and here we have a l->setParent(this); So layout_2 should be child of layout_1, Since layout_1 has a parent, it calls

    if (QWidget *mw = parentWidget()) {
            l->d_func()->reparentChildWidgets(mw);
        }
    

    that will make _qButton child of widget_1. Where did I go wrong? printing it I have that all are child of widget_1

    J 1 Reply Last reply 13 Jun 2022, 07:36
    0
    • L leonardoMB
      13 Jun 2022, 03:27

      Hi I have the following:

      QWidget *widget_1 = new QWidget(this);
      QGridLayout *layout_1 = new QGridLayout;
      widget_1->setLayout(layout_1);
      QGridLayout *layout_2 = new QGridLayout;
      layout_2->addWidget(_qButton, 0, 0, 1, 2, Qt::AlignHCenter);
      layout_1->addLayout(layout_2,0,1);
      

      So I would expect that layout_1 and _qButton are child of widget_1, meanwhile layout_2 should be child of layout_1.
      Here is why: addLayout call adoptLayout that calls
      addChildLayout(layout_2) and here we have a l->setParent(this); So layout_2 should be child of layout_1, Since layout_1 has a parent, it calls

      if (QWidget *mw = parentWidget()) {
              l->d_func()->reparentChildWidgets(mw);
          }
      

      that will make _qButton child of widget_1. Where did I go wrong? printing it I have that all are child of widget_1

      J Online
      J Online
      J.Hilk
      Moderators
      wrote on 13 Jun 2022, 07:36 last edited by J.Hilk
      #2

      @leonardoMB Layouts are not qwidgets nor qobjects in general therefore they can not be the parent of anything -> the parent responsibility is passed on


      Correction: they are indeed QObjects !


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      L 1 Reply Last reply 13 Jun 2022, 12:07
      1
      • J J.Hilk
        13 Jun 2022, 07:36

        @leonardoMB Layouts are not qwidgets nor qobjects in general therefore they can not be the parent of anything -> the parent responsibility is passed on


        Correction: they are indeed QObjects !

        L Offline
        L Offline
        leonardoMB
        wrote on 13 Jun 2022, 12:07 last edited by
        #3

        @J-Hilk but what is with this function so?

        void QLayout::addChildLayout(QLayout *l)
        {
            if (Q_UNLIKELY(l->parent())) {
                qWarning("QLayout::addChildLayout: layout \"%ls\" already has a parent",
                         qUtf16Printable(l->objectName()));
                return;
            }
            l->setParent(this);
            if (QWidget *mw = parentWidget()) {
                l->d_func()->reparentChildWidgets(mw);
            }
        }
        

        This is setting the parent of a lyout to a layout

        J 1 Reply Last reply 13 Jun 2022, 12:19
        1
        • L leonardoMB
          13 Jun 2022, 12:07

          @J-Hilk but what is with this function so?

          void QLayout::addChildLayout(QLayout *l)
          {
              if (Q_UNLIKELY(l->parent())) {
                  qWarning("QLayout::addChildLayout: layout \"%ls\" already has a parent",
                           qUtf16Printable(l->objectName()));
                  return;
              }
              l->setParent(this);
              if (QWidget *mw = parentWidget()) {
                  l->d_func()->reparentChildWidgets(mw);
              }
          }
          

          This is setting the parent of a lyout to a layout

          J Online
          J Online
          J.Hilk
          Moderators
          wrote on 13 Jun 2022, 12:19 last edited by
          #4

          @leonardoMB
          thank you for looking up and correcting me :D

          I was wrong, QLayout has QObject as a base class
          https://doc.qt.io/qt-6/qlayout.html and does take ownership and manages lifetime etc

          mmh,

          can you post/explain a bit more of your example case, I don't think I understood it correctly!


          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          L 1 Reply Last reply 13 Jun 2022, 12:36
          0
          • J J.Hilk
            13 Jun 2022, 12:19

            @leonardoMB
            thank you for looking up and correcting me :D

            I was wrong, QLayout has QObject as a base class
            https://doc.qt.io/qt-6/qlayout.html and does take ownership and manages lifetime etc

            mmh,

            can you post/explain a bit more of your example case, I don't think I understood it correctly!

            L Offline
            L Offline
            leonardoMB
            wrote on 13 Jun 2022, 12:36 last edited by leonardoMB
            #5

            @J-Hilk No problem, thanks too for helping me.
            For sure, I noticed that I forgot one line of code in the question. I edited, sorry:

            widget_1->setLayout(layout_1); //This will call the following function:
            void QWidget::setLayout(QLayout *l) //This function will set layout_1 as a child of widget_1
            

            The next step is:

            layout_2->addWidget(_qButton, 0, 0, 1, 2, Qt::AlignHCenter); //this one will call QLayout::addWidget
            
            void QLayout::addWidget(QWidget *w)
            {
                addChildWidget(w); //will call addChildWidget but since layout_2 hasn't parent nothing will change
                addItem(QLayoutPrivate::createWidgetItem(this, w));
            }
            
            

            In the last line we have:

            layout_1->addLayout(layout_2); 
            //that calls addLayout(), that calls QWidget::adoptLayout(QLayout *layout) that calls QWidget::addChildLayout(QLayout * layout)
            

            So, for me this last function QWidget::addChildLayout(QLayout * layout) will reparent the items of layout_2 to widget_1 and will set the parent of layout_2 to layout_1. But it's not what happens, everything becomes child of widget_1 in the end

            J 1 Reply Last reply 13 Jun 2022, 13:01
            0
            • L leonardoMB
              13 Jun 2022, 12:36

              @J-Hilk No problem, thanks too for helping me.
              For sure, I noticed that I forgot one line of code in the question. I edited, sorry:

              widget_1->setLayout(layout_1); //This will call the following function:
              void QWidget::setLayout(QLayout *l) //This function will set layout_1 as a child of widget_1
              

              The next step is:

              layout_2->addWidget(_qButton, 0, 0, 1, 2, Qt::AlignHCenter); //this one will call QLayout::addWidget
              
              void QLayout::addWidget(QWidget *w)
              {
                  addChildWidget(w); //will call addChildWidget but since layout_2 hasn't parent nothing will change
                  addItem(QLayoutPrivate::createWidgetItem(this, w));
              }
              
              

              In the last line we have:

              layout_1->addLayout(layout_2); 
              //that calls addLayout(), that calls QWidget::adoptLayout(QLayout *layout) that calls QWidget::addChildLayout(QLayout * layout)
              

              So, for me this last function QWidget::addChildLayout(QLayout * layout) will reparent the items of layout_2 to widget_1 and will set the parent of layout_2 to layout_1. But it's not what happens, everything becomes child of widget_1 in the end

              J Online
              J Online
              J.Hilk
              Moderators
              wrote on 13 Jun 2022, 13:01 last edited by J.Hilk
              #6

              @leonardoMB
              this

                  if (QWidget *mw = parentWidget()) {
                      l->d_func()->reparentChildWidgets(mw);
                  }
              

              is clearly a wrong if condition, I think it evaluates to always true, but that may be compiler dependent.

              I would blame all strange behaviour on that :D

              First I thought its a copy and past error on your side, but it seems to be in the latest dev branch, If I checked that correctly.


              long day.


              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


              Q: What's that?
              A: It's blue light.
              Q: What does it do?
              A: It turns blue.

              J 1 Reply Last reply 13 Jun 2022, 13:42
              1
              • J J.Hilk
                13 Jun 2022, 13:01

                @leonardoMB
                this

                    if (QWidget *mw = parentWidget()) {
                        l->d_func()->reparentChildWidgets(mw);
                    }
                

                is clearly a wrong if condition, I think it evaluates to always true, but that may be compiler dependent.

                I would blame all strange behaviour on that :D

                First I thought its a copy and past error on your side, but it seems to be in the latest dev branch, If I checked that correctly.


                long day.

                J Offline
                J Offline
                JonB
                wrote on 13 Jun 2022, 13:42 last edited by JonB
                #7

                @J-Hilk said in Why Layout is reparenting to the top most widget through addChildLayout?:

                is clearly a wrong if condition, I think it evaluates to always true, but that may be compiler dependent.

                Sorry, why?
                It's just an assign-and-test, so it sets mw to parentWidget(). IF THAT IS != nullptr it goes into if body, if it's nullptr it does not execute the body. Therefore it will never reparentChildWidgets(nullptr). Is that what you were talking about?
                The only compiler-dependency is whether it chooses to issue a warning (not error) message for naked-assignment-within-condition.

                L 1 Reply Last reply 14 Jun 2022, 13:53
                1
                • J JonB
                  13 Jun 2022, 13:42

                  @J-Hilk said in Why Layout is reparenting to the top most widget through addChildLayout?:

                  is clearly a wrong if condition, I think it evaluates to always true, but that may be compiler dependent.

                  Sorry, why?
                  It's just an assign-and-test, so it sets mw to parentWidget(). IF THAT IS != nullptr it goes into if body, if it's nullptr it does not execute the body. Therefore it will never reparentChildWidgets(nullptr). Is that what you were talking about?
                  The only compiler-dependency is whether it chooses to issue a warning (not error) message for naked-assignment-within-condition.

                  L Offline
                  L Offline
                  leonardoMB
                  wrote on 14 Jun 2022, 13:53 last edited by
                  #8

                  @JonB So if it's not compile dependent I really didn't understand why I didn't get what I expected

                  1 Reply Last reply
                  0
                  • J Online
                    J Online
                    JoeCFD
                    wrote on 14 Jun 2022, 14:03 last edited by
                    #9

                    @leonardoMB said in Why Layout is reparenting to the top most widget through addChildLayout?:

                    What will make _qButton child of widget_1. Where did I go wrong? printing it I have that all are child of widget_1

                    What will make _qButton child of widget_1?
                    _qButton = new QPushButton( widget_1 ) or _qButton->setParent( widget_1 ); will make _qButton the child of widget_1.
                    The layouts of widget_1 can have children of other widgets.

                    1 Reply Last reply
                    0

                    9/9

                    14 Jun 2022, 14:03

                    • Login

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