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. QVBoxLayout just stacking widgets on top of each other
QtWS25 Last Chance

QVBoxLayout just stacking widgets on top of each other

Scheduled Pinned Locked Moved Solved General and Desktop
qscrollareaqvboxlayoutqwidgetlistwidgetlist
3 Posts 2 Posters 2.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.
  • E Offline
    E Offline
    Erika_Butler
    wrote on last edited by Erika_Butler
    #1

    I have a class named VerticalWidgetList, which is meant to use a QVBoxLayout to display widgets added to it in a list from top to bottom in the order the widgets were added. I'm having a problem with it, though, as when I add widgets using addWidget(), it instead seems to stack the widgets on top of each other. Here is the source code for the class. Am I setting this up right?

    verticalwidgetlist.h

    #ifndef VERTICALWIDGETLIST_H
    #define VERTICALWIDGETLIST_H
    
    #include <QScrollArea>
    #include <QVBoxLayout>
    #include <QWidgetList>
    
    class VerticalWidgetList : public QScrollArea {
        Q_OBJECT
    public:
        explicit VerticalWidgetList(QWidget *parent = nullptr);
    
        bool addWidget(QWidget *child);
        void clearWidgets();
        bool insertWidget(int index, QWidget *child);
        bool removeWidget(int index);
        bool removeWidgetAt(QWidget *child);
        QWidget *takeWidget(int index);
        int widgetAt(QWidget *child) const;
    
    private:
        QWidget *m_central;
        QVBoxLayout *m_layout;
        QWidgetList m_list;
    
    };
    
    #endif // VERTICALWIDGETLIST_H
    
    

    verticalwidgetlist.cpp

    #include "verticalwidgetlist.h"
    
    VerticalWidgetList::VerticalWidgetList(QWidget *parent)
        : QScrollArea(parent)
        , m_central(new QWidget)
        , m_layout(new QVBoxLayout(m_central))
        , m_list()
    {
        setWidget(m_central);
        setWidgetResizable(true);
    }
    
    bool VerticalWidgetList::addWidget(QWidget *child) {
        if(child == nullptr)
            return false;
        m_layout->addWidget(child);
        m_list.append(child);
        child->setParent(this);
        return true;
    }
    
    void VerticalWidgetList::clearWidgets() {
        while(m_list.count()) {
            QWidget *widget = m_list.takeAt(0);
            m_layout->removeWidget(widget);
        }
    }
    
    bool VerticalWidgetList::insertWidget(int index, QWidget *child) {
        if(index < 0 || index > m_list.count())
            return false;
        if(child == nullptr)
            return false;
        m_layout->insertWidget(index, child);
        m_list.insert(index, child);
        child->setParent(this);
        return true;
    }
    
    bool VerticalWidgetList::removeWidget(int index) {
        if(index < 0 || index >= m_list.count())
            return false;
        QWidget *widget = m_list.takeAt(index);
        m_layout->removeWidget(widget);
        delete widget;
        return true;
    }
    
    bool VerticalWidgetList::removeWidgetAt(QWidget *child) {
        if(child == nullptr)
            return false;
        m_layout->removeWidget(child);
        int index = widgetAt(child);
        m_list.removeAt(index);
        delete child;
        return true;
    }
    
    QWidget *VerticalWidgetList::takeWidget(int index) {
        if(index < 0 || index >= m_list.count())
            return nullptr;
        QWidget *widget = m_list.takeAt(index);
        m_layout->removeWidget(widget);
        widget->setParent(nullptr);
        return widget;
    }
    
    int VerticalWidgetList::widgetAt(QWidget *child) const {
        if(child == nullptr)
            return -1;
        return m_list.indexOf(child);
    }
    
    
    jsulmJ 1 Reply Last reply
    0
    • jsulmJ jsulm

      @Erika_Butler Then use https://doc.qt.io/qt-5/qboxlayout.html#insertWidget and specify the index

      E Offline
      E Offline
      Erika_Butler
      wrote on last edited by Erika_Butler
      #3

      @jsulm Fortunately, I just solved it. I should not have specified the VerticalWidgetList class as the parent of the widgets added. Apparently, when you add it to the layout, the widgets added get some sort of other parent class. I still nullptr out the widget in the takeWidget() function, however, as control of it should pass to the function receiving the return value. When I got rid of setting the parent in the addWidget() and insertWidget() functions, it now works properly.

      I do wonder if I should still delete the child widget in removeWidget() and removeWidgetAt() after removing it from the layout. Or do I need to set the parent to nullptr before deleting it? When my program used clearWidgets(), which calls removeWidget(), there was no problem.

      It works now!

      This is the source code now:

      verticalwidgetlist.h

      #ifndef VERTICALWIDGETLIST_H
      #define VERTICALWIDGETLIST_H
      
      #include <QScrollArea>
      #include <QVBoxLayout>
      #include <QWidgetList>
      
      class VerticalWidgetList : public QScrollArea {
          Q_OBJECT
      public:
          explicit VerticalWidgetList(QWidget *parent = nullptr);
      
          bool addWidget(QWidget *child);
          void clearWidgets();
          bool insertWidget(int index, QWidget *child);
          bool removeWidget(QWidget *child;
          bool removeWidgetAt(int index);
          QWidget *takeWidget(int index);
          int widgetAt(QWidget *child) const;
      
      private:
          QWidget *m_central;
          QVBoxLayout *m_layout;
          QWidgetList m_list;
      
      };
      
      #endif // VERTICALWIDGETLIST_H
      
      

      verticalwidgetlist.cpp

      #include "verticalwidgetlist.h"
      
      VerticalWidgetList::VerticalWidgetList(QWidget *parent)
          : QScrollArea(parent)
          , m_central(new QWidget)
          , m_layout(new QVBoxLayout(m_central))
          , m_list()
      {
          setWidget(m_central);
          setWidgetResizable(true);
      }
      
      bool VerticalWidgetList::addWidget(QWidget *child) {
          if(child == nullptr)
              return false;
          m_layout->addWidget(child);
          m_list.append(child);
          return true;
      }
      
      void VerticalWidgetList::clearWidgets() {
          while(m_list.count()) {
              QWidget *widget = m_list[0];
              removeWidget(widget);
          }
      }
      
      bool VerticalWidgetList::insertWidget(int index, QWidget *child) {
          if(index < 0 || index > m_list.count())
              return false;
          if(child == nullptr)
              return false;
          m_layout->insertWidget(index, child);
          m_list.insert(index, child);
          return true;
      }
      
      bool VerticalWidgetList::removeWidget(QWidget *child) {
          if(child == nullptr)
              return false;
          m_layout->removeWidget(child);
          int index = widgetAt(child);
          m_list.removeAt(index);
          delete child;
          return true;
      }
      
      bool VerticalWidgetList::removeWidgetAt(int index) {
          if(index < 0 || index >= m_list.count())
              return false;
          QWidget *widget = m_list.takeAt(index);
          m_layout->removeWidget(widget);
          delete widget;
          return true;
      }
      
      QWidget *VerticalWidgetList::takeWidget(int index) {
          if(index < 0 || index >= m_list.count())
              return nullptr;
          QWidget *widget = m_list.takeAt(index);
          m_layout->removeWidget(widget);
          widget->setParent(nullptr);
          return widget;
      }
      
      int VerticalWidgetList::widgetAt(QWidget *child) const {
          if(child == nullptr)
              return -1;
          return m_list.indexOf(child);
      }
      
      

      EDIT: If anyone tried the source code up until this point, in this post, try again. I was rearranging removeWidget() and removeWidgetAt(), which I realized were mismatched in terms of their parameters. It's good now!

      1 Reply Last reply
      0
      • E Erika_Butler

        I have a class named VerticalWidgetList, which is meant to use a QVBoxLayout to display widgets added to it in a list from top to bottom in the order the widgets were added. I'm having a problem with it, though, as when I add widgets using addWidget(), it instead seems to stack the widgets on top of each other. Here is the source code for the class. Am I setting this up right?

        verticalwidgetlist.h

        #ifndef VERTICALWIDGETLIST_H
        #define VERTICALWIDGETLIST_H
        
        #include <QScrollArea>
        #include <QVBoxLayout>
        #include <QWidgetList>
        
        class VerticalWidgetList : public QScrollArea {
            Q_OBJECT
        public:
            explicit VerticalWidgetList(QWidget *parent = nullptr);
        
            bool addWidget(QWidget *child);
            void clearWidgets();
            bool insertWidget(int index, QWidget *child);
            bool removeWidget(int index);
            bool removeWidgetAt(QWidget *child);
            QWidget *takeWidget(int index);
            int widgetAt(QWidget *child) const;
        
        private:
            QWidget *m_central;
            QVBoxLayout *m_layout;
            QWidgetList m_list;
        
        };
        
        #endif // VERTICALWIDGETLIST_H
        
        

        verticalwidgetlist.cpp

        #include "verticalwidgetlist.h"
        
        VerticalWidgetList::VerticalWidgetList(QWidget *parent)
            : QScrollArea(parent)
            , m_central(new QWidget)
            , m_layout(new QVBoxLayout(m_central))
            , m_list()
        {
            setWidget(m_central);
            setWidgetResizable(true);
        }
        
        bool VerticalWidgetList::addWidget(QWidget *child) {
            if(child == nullptr)
                return false;
            m_layout->addWidget(child);
            m_list.append(child);
            child->setParent(this);
            return true;
        }
        
        void VerticalWidgetList::clearWidgets() {
            while(m_list.count()) {
                QWidget *widget = m_list.takeAt(0);
                m_layout->removeWidget(widget);
            }
        }
        
        bool VerticalWidgetList::insertWidget(int index, QWidget *child) {
            if(index < 0 || index > m_list.count())
                return false;
            if(child == nullptr)
                return false;
            m_layout->insertWidget(index, child);
            m_list.insert(index, child);
            child->setParent(this);
            return true;
        }
        
        bool VerticalWidgetList::removeWidget(int index) {
            if(index < 0 || index >= m_list.count())
                return false;
            QWidget *widget = m_list.takeAt(index);
            m_layout->removeWidget(widget);
            delete widget;
            return true;
        }
        
        bool VerticalWidgetList::removeWidgetAt(QWidget *child) {
            if(child == nullptr)
                return false;
            m_layout->removeWidget(child);
            int index = widgetAt(child);
            m_list.removeAt(index);
            delete child;
            return true;
        }
        
        QWidget *VerticalWidgetList::takeWidget(int index) {
            if(index < 0 || index >= m_list.count())
                return nullptr;
            QWidget *widget = m_list.takeAt(index);
            m_layout->removeWidget(widget);
            widget->setParent(nullptr);
            return widget;
        }
        
        int VerticalWidgetList::widgetAt(QWidget *child) const {
            if(child == nullptr)
                return -1;
            return m_list.indexOf(child);
        }
        
        
        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #2

        @Erika_Butler Then use https://doc.qt.io/qt-5/qboxlayout.html#insertWidget and specify the index

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        E 1 Reply Last reply
        0
        • jsulmJ jsulm

          @Erika_Butler Then use https://doc.qt.io/qt-5/qboxlayout.html#insertWidget and specify the index

          E Offline
          E Offline
          Erika_Butler
          wrote on last edited by Erika_Butler
          #3

          @jsulm Fortunately, I just solved it. I should not have specified the VerticalWidgetList class as the parent of the widgets added. Apparently, when you add it to the layout, the widgets added get some sort of other parent class. I still nullptr out the widget in the takeWidget() function, however, as control of it should pass to the function receiving the return value. When I got rid of setting the parent in the addWidget() and insertWidget() functions, it now works properly.

          I do wonder if I should still delete the child widget in removeWidget() and removeWidgetAt() after removing it from the layout. Or do I need to set the parent to nullptr before deleting it? When my program used clearWidgets(), which calls removeWidget(), there was no problem.

          It works now!

          This is the source code now:

          verticalwidgetlist.h

          #ifndef VERTICALWIDGETLIST_H
          #define VERTICALWIDGETLIST_H
          
          #include <QScrollArea>
          #include <QVBoxLayout>
          #include <QWidgetList>
          
          class VerticalWidgetList : public QScrollArea {
              Q_OBJECT
          public:
              explicit VerticalWidgetList(QWidget *parent = nullptr);
          
              bool addWidget(QWidget *child);
              void clearWidgets();
              bool insertWidget(int index, QWidget *child);
              bool removeWidget(QWidget *child;
              bool removeWidgetAt(int index);
              QWidget *takeWidget(int index);
              int widgetAt(QWidget *child) const;
          
          private:
              QWidget *m_central;
              QVBoxLayout *m_layout;
              QWidgetList m_list;
          
          };
          
          #endif // VERTICALWIDGETLIST_H
          
          

          verticalwidgetlist.cpp

          #include "verticalwidgetlist.h"
          
          VerticalWidgetList::VerticalWidgetList(QWidget *parent)
              : QScrollArea(parent)
              , m_central(new QWidget)
              , m_layout(new QVBoxLayout(m_central))
              , m_list()
          {
              setWidget(m_central);
              setWidgetResizable(true);
          }
          
          bool VerticalWidgetList::addWidget(QWidget *child) {
              if(child == nullptr)
                  return false;
              m_layout->addWidget(child);
              m_list.append(child);
              return true;
          }
          
          void VerticalWidgetList::clearWidgets() {
              while(m_list.count()) {
                  QWidget *widget = m_list[0];
                  removeWidget(widget);
              }
          }
          
          bool VerticalWidgetList::insertWidget(int index, QWidget *child) {
              if(index < 0 || index > m_list.count())
                  return false;
              if(child == nullptr)
                  return false;
              m_layout->insertWidget(index, child);
              m_list.insert(index, child);
              return true;
          }
          
          bool VerticalWidgetList::removeWidget(QWidget *child) {
              if(child == nullptr)
                  return false;
              m_layout->removeWidget(child);
              int index = widgetAt(child);
              m_list.removeAt(index);
              delete child;
              return true;
          }
          
          bool VerticalWidgetList::removeWidgetAt(int index) {
              if(index < 0 || index >= m_list.count())
                  return false;
              QWidget *widget = m_list.takeAt(index);
              m_layout->removeWidget(widget);
              delete widget;
              return true;
          }
          
          QWidget *VerticalWidgetList::takeWidget(int index) {
              if(index < 0 || index >= m_list.count())
                  return nullptr;
              QWidget *widget = m_list.takeAt(index);
              m_layout->removeWidget(widget);
              widget->setParent(nullptr);
              return widget;
          }
          
          int VerticalWidgetList::widgetAt(QWidget *child) const {
              if(child == nullptr)
                  return -1;
              return m_list.indexOf(child);
          }
          
          

          EDIT: If anyone tried the source code up until this point, in this post, try again. I was rearranging removeWidget() and removeWidgetAt(), which I realized were mismatched in terms of their parameters. It's good now!

          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