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. Widget doesn't take the whole vertical space
Forum Updated to NodeBB v4.3 + New Features

Widget doesn't take the whole vertical space

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 5 Posters 632 Views 2 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.
  • A Offline
    A Offline
    AntonBogun
    wrote on last edited by
    #1

    I am trying to make a sort of notification system in my project similar to vscode, and I am currently doing this by just adding the widget responsible for displaying the notifications directly as a child to the QMainWindow, and then manually keeping its horizontal (fixed) and max vertical (true vertical is supposed to depend on number of notifications) size updated whenever the window gets resized.
    Here is the code how I do it:

    //mainwindow.cpp, modified from diagramscene example
    MainWindow::MainWindow()
    {
    ...
        m_notificationWidget=new NotificationWidget(this);
        for(int i=0; i<10; i++){
            m_notificationWidget->addNotification("Notification "+QString::number(i));
        }
    
        updateNotificationWidgetPosition();
        m_notificationWidget->show();
        m_notificationWidget->raise();
    }
    void MainWindow::updateNotificationWidgetPosition() {
        int newX = width() - m_notificationWidget->width() - 0.03 * width();
        int newY = height() - m_notificationWidget->height() - 0.03 * height();
        m_notificationWidget->move(newX, newY);
        m_notificationWidget->setFixedWidth(qMin(300, width()*4/5));
        m_notificationWidget->setMaximumHeight(height());
    }
    void MainWindow::resizeEvent(QResizeEvent *event) {
        QMainWindow::resizeEvent(event);
        updateNotificationWidgetPosition();
    }
    
    //notificationwidget.cpp
    NotificationWidget::NotificationWidget(QWidget *parent) 
        : QWidget(parent), 
          m_layout(new QVBoxLayout(this)), 
          m_scrollArea(new QScrollArea(this)), 
          m_scrollWidget(new QWidget), 
          m_scrollLayout(new QVBoxLayout(m_scrollWidget)) 
    {
        m_scrollArea->setWidget(m_scrollWidget);
        m_scrollArea->setWidgetResizable(true);
        m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
        
        m_scrollWidget->setLayout(m_scrollLayout);
        m_layout->addWidget(m_scrollArea);
        setLayout(m_layout);
    
        setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
        m_scrollArea->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
        m_scrollWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
    
        setFixedWidth(qMin(300, parentWidget()->width() *4/5));
        setMaximumHeight(parentWidget()->height());
    }
    
    void NotificationWidget::addNotification(const QString &message) {
        QLabel *label = new QLabel(message, this);
        label->setWordWrap(true);
        m_scrollLayout->addWidget(label);
        _adjustSize();
    }
    
    void NotificationWidget::resizeEvent(QResizeEvent *event) {
        QWidget::resizeEvent(event);
        setFixedWidth(qMin(300, parentWidget()->width() *4/5));
        setMaximumHeight(parentWidget()->height());
        adjustSize();
    }
    void NotificationWidget::_adjustSize() {
        m_scrollWidget->adjustSize();
        m_scrollArea->adjustSize();
        adjustSize();
    }
    

    This is what it ends up looking like:
    cfc11453-d34a-4026-839a-b1215957d3f6-image.png

    Now, as you can see the problem is that the notification widget takes very little vertical space compared to what it should take and should be able to take, in fact I think it is about as much as adding just a single notification.
    I will say in advance that I kind of have no idea what I'm doing since I don't know of a place where manual widget placement like this is documented, and it seems you can't actually do this with layouts, but I thought that this would work.

    M jsulmJ M 3 Replies Last reply
    0
    • M mpergand

      @AntonBogun said in Widget doesn't take the whole vertical space:

      Is it possible to somehow add "another" layout on top of what MainWindow does, and have it draw over what MainWindow draws? I get the impression of the QWidget::setLayout() that it is not the case,

      You can add a layout to a QBoxLayout:
      void QBoxLayout::addLayout(QLayout *layout, int stretch = 0)

      A Offline
      A Offline
      AntonBogun
      wrote on last edited by AntonBogun
      #7

      @mpergand said in Widget doesn't take the whole vertical space:

      @AntonBogun said in Widget doesn't take the whole vertical space:

      Is it possible to somehow add "another" layout on top of what MainWindow does, and have it draw over what MainWindow draws? I get the impression of the QWidget::setLayout() that it is not the case,

      You can add a layout to a QBoxLayout:
      void QBoxLayout::addLayout(QLayout *layout, int stretch = 0)

      From what I've tested, adding child layouts to other layouts does not in fact allow them to overlap and have one of them draw on top of the other.

      Also, I actually managed to solve it by thinking about it some more and tweaking it until it started working:

      //notificationwidget.h
      NotificationWidget::NotificationWidget(QWidget *parent) 
          : QScrollArea(parent),
            m_scrollWidget(new QWidget), 
            m_scrollLayout(new QVBoxLayout(m_scrollWidget)) 
      {
          setWidget(m_scrollWidget);
          setWidgetResizable(true);
          setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
      
          m_scrollWidget->setLayout(m_scrollLayout);
      
          setFixedWidth(qMin(300, parentWidget()->width() *4/5));
          setMaximumHeight(0.6*parentWidget()->height());
      }
      QSize NotificationWidget::sizeHint() const {
          return m_scrollWidget->sizeHint()+QSize(0,2); // without +2 scroll bar appears
      }
      
      void NotificationWidget::addNotification(const QString &message) {
          QLabel *label = new QLabel(message, this);
          label->setWordWrap(true);
          m_scrollLayout->addWidget(label);
          m_scrollWidget->adjustSize();
          adjustSize();
      }
      
      void NotificationWidget::resizeEvent(QResizeEvent *event) {
          QWidget::resizeEvent(event);
          setFixedWidth(qMin(300, parentWidget()->width() *4/5));
          setMaximumHeight(0.6*parentWidget()->height());
          m_scrollWidget->adjustSize();//necessary
          adjustSize();
      }
      
      //mainwindow.cpp
      void MainWindow::updateNotificationWidgetPosition() {
          m_notificationWidget->setFixedWidth(qMin(300, width() *4/5));
          m_notificationWidget->setMaximumHeight(height());
          m_notificationWidget->adjustSize();//necessary
          int newX = width() - m_notificationWidget->width() - 0.03 * width();
          int newY = height() - m_notificationWidget->height() - 0.03 * height();
          m_notificationWidget->move(newX, newY);
      }
      

      Everyone so far seems to have missed the point that this should overlap and draw over the existing contents of the mainwindow, and afaik you can't do that with a layout.
      The gif of the final result, notice specifically how the goal is for the NotificationWidget to overlap over other contents.

      I still wonder if there is some less hacky way to do this though. And possibly it could break in some edge cases which I'm unaware of.
      I'll leave this open for a bit so that maybe someone can post a better solution to get this behaviour.

      1 Reply Last reply
      0
      • A AntonBogun

        I am trying to make a sort of notification system in my project similar to vscode, and I am currently doing this by just adding the widget responsible for displaying the notifications directly as a child to the QMainWindow, and then manually keeping its horizontal (fixed) and max vertical (true vertical is supposed to depend on number of notifications) size updated whenever the window gets resized.
        Here is the code how I do it:

        //mainwindow.cpp, modified from diagramscene example
        MainWindow::MainWindow()
        {
        ...
            m_notificationWidget=new NotificationWidget(this);
            for(int i=0; i<10; i++){
                m_notificationWidget->addNotification("Notification "+QString::number(i));
            }
        
            updateNotificationWidgetPosition();
            m_notificationWidget->show();
            m_notificationWidget->raise();
        }
        void MainWindow::updateNotificationWidgetPosition() {
            int newX = width() - m_notificationWidget->width() - 0.03 * width();
            int newY = height() - m_notificationWidget->height() - 0.03 * height();
            m_notificationWidget->move(newX, newY);
            m_notificationWidget->setFixedWidth(qMin(300, width()*4/5));
            m_notificationWidget->setMaximumHeight(height());
        }
        void MainWindow::resizeEvent(QResizeEvent *event) {
            QMainWindow::resizeEvent(event);
            updateNotificationWidgetPosition();
        }
        
        //notificationwidget.cpp
        NotificationWidget::NotificationWidget(QWidget *parent) 
            : QWidget(parent), 
              m_layout(new QVBoxLayout(this)), 
              m_scrollArea(new QScrollArea(this)), 
              m_scrollWidget(new QWidget), 
              m_scrollLayout(new QVBoxLayout(m_scrollWidget)) 
        {
            m_scrollArea->setWidget(m_scrollWidget);
            m_scrollArea->setWidgetResizable(true);
            m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
            
            m_scrollWidget->setLayout(m_scrollLayout);
            m_layout->addWidget(m_scrollArea);
            setLayout(m_layout);
        
            setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
            m_scrollArea->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
            m_scrollWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
        
            setFixedWidth(qMin(300, parentWidget()->width() *4/5));
            setMaximumHeight(parentWidget()->height());
        }
        
        void NotificationWidget::addNotification(const QString &message) {
            QLabel *label = new QLabel(message, this);
            label->setWordWrap(true);
            m_scrollLayout->addWidget(label);
            _adjustSize();
        }
        
        void NotificationWidget::resizeEvent(QResizeEvent *event) {
            QWidget::resizeEvent(event);
            setFixedWidth(qMin(300, parentWidget()->width() *4/5));
            setMaximumHeight(parentWidget()->height());
            adjustSize();
        }
        void NotificationWidget::_adjustSize() {
            m_scrollWidget->adjustSize();
            m_scrollArea->adjustSize();
            adjustSize();
        }
        

        This is what it ends up looking like:
        cfc11453-d34a-4026-839a-b1215957d3f6-image.png

        Now, as you can see the problem is that the notification widget takes very little vertical space compared to what it should take and should be able to take, in fact I think it is about as much as adding just a single notification.
        I will say in advance that I kind of have no idea what I'm doing since I don't know of a place where manual widget placement like this is documented, and it seems you can't actually do this with layouts, but I thought that this would work.

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

        @AntonBogun
        It seems you need to put your NotificationWidget as centralWidget of the mainWindow.

        Apart from that, I don't understand what you are trying to do in updateNotificationWidgetPosition()

        A 1 Reply Last reply
        0
        • A AntonBogun

          I am trying to make a sort of notification system in my project similar to vscode, and I am currently doing this by just adding the widget responsible for displaying the notifications directly as a child to the QMainWindow, and then manually keeping its horizontal (fixed) and max vertical (true vertical is supposed to depend on number of notifications) size updated whenever the window gets resized.
          Here is the code how I do it:

          //mainwindow.cpp, modified from diagramscene example
          MainWindow::MainWindow()
          {
          ...
              m_notificationWidget=new NotificationWidget(this);
              for(int i=0; i<10; i++){
                  m_notificationWidget->addNotification("Notification "+QString::number(i));
              }
          
              updateNotificationWidgetPosition();
              m_notificationWidget->show();
              m_notificationWidget->raise();
          }
          void MainWindow::updateNotificationWidgetPosition() {
              int newX = width() - m_notificationWidget->width() - 0.03 * width();
              int newY = height() - m_notificationWidget->height() - 0.03 * height();
              m_notificationWidget->move(newX, newY);
              m_notificationWidget->setFixedWidth(qMin(300, width()*4/5));
              m_notificationWidget->setMaximumHeight(height());
          }
          void MainWindow::resizeEvent(QResizeEvent *event) {
              QMainWindow::resizeEvent(event);
              updateNotificationWidgetPosition();
          }
          
          //notificationwidget.cpp
          NotificationWidget::NotificationWidget(QWidget *parent) 
              : QWidget(parent), 
                m_layout(new QVBoxLayout(this)), 
                m_scrollArea(new QScrollArea(this)), 
                m_scrollWidget(new QWidget), 
                m_scrollLayout(new QVBoxLayout(m_scrollWidget)) 
          {
              m_scrollArea->setWidget(m_scrollWidget);
              m_scrollArea->setWidgetResizable(true);
              m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
              
              m_scrollWidget->setLayout(m_scrollLayout);
              m_layout->addWidget(m_scrollArea);
              setLayout(m_layout);
          
              setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
              m_scrollArea->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
              m_scrollWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
          
              setFixedWidth(qMin(300, parentWidget()->width() *4/5));
              setMaximumHeight(parentWidget()->height());
          }
          
          void NotificationWidget::addNotification(const QString &message) {
              QLabel *label = new QLabel(message, this);
              label->setWordWrap(true);
              m_scrollLayout->addWidget(label);
              _adjustSize();
          }
          
          void NotificationWidget::resizeEvent(QResizeEvent *event) {
              QWidget::resizeEvent(event);
              setFixedWidth(qMin(300, parentWidget()->width() *4/5));
              setMaximumHeight(parentWidget()->height());
              adjustSize();
          }
          void NotificationWidget::_adjustSize() {
              m_scrollWidget->adjustSize();
              m_scrollArea->adjustSize();
              adjustSize();
          }
          

          This is what it ends up looking like:
          cfc11453-d34a-4026-839a-b1215957d3f6-image.png

          Now, as you can see the problem is that the notification widget takes very little vertical space compared to what it should take and should be able to take, in fact I think it is about as much as adding just a single notification.
          I will say in advance that I kind of have no idea what I'm doing since I don't know of a place where manual widget placement like this is documented, and it seems you can't actually do this with layouts, but I thought that this would work.

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #3

          @AntonBogun said in Widget doesn't take the whole vertical space:

          size updated whenever the window gets resized.

          Why don't you simply use layouts?! https://doc.qt.io/qt-6/layout.html

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

          1 Reply Last reply
          0
          • A AntonBogun

            I am trying to make a sort of notification system in my project similar to vscode, and I am currently doing this by just adding the widget responsible for displaying the notifications directly as a child to the QMainWindow, and then manually keeping its horizontal (fixed) and max vertical (true vertical is supposed to depend on number of notifications) size updated whenever the window gets resized.
            Here is the code how I do it:

            //mainwindow.cpp, modified from diagramscene example
            MainWindow::MainWindow()
            {
            ...
                m_notificationWidget=new NotificationWidget(this);
                for(int i=0; i<10; i++){
                    m_notificationWidget->addNotification("Notification "+QString::number(i));
                }
            
                updateNotificationWidgetPosition();
                m_notificationWidget->show();
                m_notificationWidget->raise();
            }
            void MainWindow::updateNotificationWidgetPosition() {
                int newX = width() - m_notificationWidget->width() - 0.03 * width();
                int newY = height() - m_notificationWidget->height() - 0.03 * height();
                m_notificationWidget->move(newX, newY);
                m_notificationWidget->setFixedWidth(qMin(300, width()*4/5));
                m_notificationWidget->setMaximumHeight(height());
            }
            void MainWindow::resizeEvent(QResizeEvent *event) {
                QMainWindow::resizeEvent(event);
                updateNotificationWidgetPosition();
            }
            
            //notificationwidget.cpp
            NotificationWidget::NotificationWidget(QWidget *parent) 
                : QWidget(parent), 
                  m_layout(new QVBoxLayout(this)), 
                  m_scrollArea(new QScrollArea(this)), 
                  m_scrollWidget(new QWidget), 
                  m_scrollLayout(new QVBoxLayout(m_scrollWidget)) 
            {
                m_scrollArea->setWidget(m_scrollWidget);
                m_scrollArea->setWidgetResizable(true);
                m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
                
                m_scrollWidget->setLayout(m_scrollLayout);
                m_layout->addWidget(m_scrollArea);
                setLayout(m_layout);
            
                setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
                m_scrollArea->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
                m_scrollWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
            
                setFixedWidth(qMin(300, parentWidget()->width() *4/5));
                setMaximumHeight(parentWidget()->height());
            }
            
            void NotificationWidget::addNotification(const QString &message) {
                QLabel *label = new QLabel(message, this);
                label->setWordWrap(true);
                m_scrollLayout->addWidget(label);
                _adjustSize();
            }
            
            void NotificationWidget::resizeEvent(QResizeEvent *event) {
                QWidget::resizeEvent(event);
                setFixedWidth(qMin(300, parentWidget()->width() *4/5));
                setMaximumHeight(parentWidget()->height());
                adjustSize();
            }
            void NotificationWidget::_adjustSize() {
                m_scrollWidget->adjustSize();
                m_scrollArea->adjustSize();
                adjustSize();
            }
            

            This is what it ends up looking like:
            cfc11453-d34a-4026-839a-b1215957d3f6-image.png

            Now, as you can see the problem is that the notification widget takes very little vertical space compared to what it should take and should be able to take, in fact I think it is about as much as adding just a single notification.
            I will say in advance that I kind of have no idea what I'm doing since I don't know of a place where manual widget placement like this is documented, and it seems you can't actually do this with layouts, but I thought that this would work.

            M Offline
            M Offline
            medyakovvit
            wrote on last edited by
            #4

            @AntonBogun As I understand, you want the notification to have the size so all items in the scroll view are visible. If your notification popup has only the scroll view then you can inherit NotificationWidget from the QScrollArea. Then you can override viewportSizeHint() function so it returns the height required for all items. And, I'm not sure, you also need sizeAdjustPolicy() set to QAbstractScrollArea::AdjustToContents

            1 Reply Last reply
            0
            • M mpergand

              @AntonBogun
              It seems you need to put your NotificationWidget as centralWidget of the mainWindow.

              Apart from that, I don't understand what you are trying to do in updateNotificationWidgetPosition()

              A Offline
              A Offline
              AntonBogun
              wrote on last edited by
              #5

              @mpergand said in Widget doesn't take the whole vertical space:

              @AntonBogun
              It seems you need to put your NotificationWidget as centralWidget of the mainWindow.

              Apart from that, I don't understand what you are trying to do in updateNotificationWidgetPosition()

              The entire point is for this widget to be on top of the centralWidget (actually ideally also above the dockWidgets, but for now if i can get it to consistently go above anything I will take it), and that it stays in the corner and takes up some small part of the screen, which would depend on the amount of notifications.
              The updateNotificationWidgetPosition is an attempt at a manual resize of the NotificationWidget whenever the mainWindow resizes, basically trying to do a layout myself. You can see a more detailed explanation below:

              @jsulm said in Widget doesn't take the whole vertical space:

              @AntonBogun said in Widget doesn't take the whole vertical space:

              size updated whenever the window gets resized.

              Why don't you simply use layouts?! https://doc.qt.io/qt-6/layout.html

              Is it possible to somehow add "another" layout on top of what MainWindow does, and have it draw over what MainWindow draws? I get the impression of the QWidget::setLayout() that it is not the case, and that a given widget can only have one layout, so I would be replacing the MainWindow's layout, which is not what I want.

              @medyakovvit said in Widget doesn't take the whole vertical space:

              @AntonBogun As I understand, you want the notification to have the size so all items in the scroll view are visible. If your notification popup has only the scroll view then you can inherit NotificationWidget from the QScrollArea. Then you can override viewportSizeHint() function so it returns the height required for all items. And, I'm not sure, you also need sizeAdjustPolicy() set to QAbstractScrollArea::AdjustToContents

              This sounds like what I would want but are you sure it would respect the extra restrictions I would like on it based on the MainWindow's size?
              If you look at the updateNotificatoinWidgetPosition you can see what the restrictions are:

              • it should be positioned aligned to the bottom-right corner (the move(size()-notificationWidget->size()) part)
              • it shouldn't touch the bottom right corner but have some whitespace (the -0.03*size() part)
              • it should be a constant 300px wide, or 4/5th of the width of the MainWindow, whichever is smaller (setFixedWidth part)
              • it shouldn't exceed the height of the MainWindow (setMaximumHeight part)
              • it should take as much vertical space as it needs, or as much as it can, whichever is smaller, and in case it needs more than it can it should create a scroll bar.

              My primary issue is that I am unsure how to meet these more complicated requirements that rely on the MainWindow, since I don't think I can use a layout without overwriting MainWindow's layout, but as you can see my own code where I try to "layout" the widget manually results in incorrect behaviour.
              I will however try what you suggested and try to change the NotificationWidget to inherit from QScrollArea.

              M 1 Reply Last reply
              0
              • A AntonBogun

                @mpergand said in Widget doesn't take the whole vertical space:

                @AntonBogun
                It seems you need to put your NotificationWidget as centralWidget of the mainWindow.

                Apart from that, I don't understand what you are trying to do in updateNotificationWidgetPosition()

                The entire point is for this widget to be on top of the centralWidget (actually ideally also above the dockWidgets, but for now if i can get it to consistently go above anything I will take it), and that it stays in the corner and takes up some small part of the screen, which would depend on the amount of notifications.
                The updateNotificationWidgetPosition is an attempt at a manual resize of the NotificationWidget whenever the mainWindow resizes, basically trying to do a layout myself. You can see a more detailed explanation below:

                @jsulm said in Widget doesn't take the whole vertical space:

                @AntonBogun said in Widget doesn't take the whole vertical space:

                size updated whenever the window gets resized.

                Why don't you simply use layouts?! https://doc.qt.io/qt-6/layout.html

                Is it possible to somehow add "another" layout on top of what MainWindow does, and have it draw over what MainWindow draws? I get the impression of the QWidget::setLayout() that it is not the case, and that a given widget can only have one layout, so I would be replacing the MainWindow's layout, which is not what I want.

                @medyakovvit said in Widget doesn't take the whole vertical space:

                @AntonBogun As I understand, you want the notification to have the size so all items in the scroll view are visible. If your notification popup has only the scroll view then you can inherit NotificationWidget from the QScrollArea. Then you can override viewportSizeHint() function so it returns the height required for all items. And, I'm not sure, you also need sizeAdjustPolicy() set to QAbstractScrollArea::AdjustToContents

                This sounds like what I would want but are you sure it would respect the extra restrictions I would like on it based on the MainWindow's size?
                If you look at the updateNotificatoinWidgetPosition you can see what the restrictions are:

                • it should be positioned aligned to the bottom-right corner (the move(size()-notificationWidget->size()) part)
                • it shouldn't touch the bottom right corner but have some whitespace (the -0.03*size() part)
                • it should be a constant 300px wide, or 4/5th of the width of the MainWindow, whichever is smaller (setFixedWidth part)
                • it shouldn't exceed the height of the MainWindow (setMaximumHeight part)
                • it should take as much vertical space as it needs, or as much as it can, whichever is smaller, and in case it needs more than it can it should create a scroll bar.

                My primary issue is that I am unsure how to meet these more complicated requirements that rely on the MainWindow, since I don't think I can use a layout without overwriting MainWindow's layout, but as you can see my own code where I try to "layout" the widget manually results in incorrect behaviour.
                I will however try what you suggested and try to change the NotificationWidget to inherit from QScrollArea.

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

                @AntonBogun said in Widget doesn't take the whole vertical space:

                Is it possible to somehow add "another" layout on top of what MainWindow does, and have it draw over what MainWindow draws? I get the impression of the QWidget::setLayout() that it is not the case,

                You can add a layout to a QBoxLayout:
                void QBoxLayout::addLayout(QLayout *layout, int stretch = 0)

                A 1 Reply Last reply
                1
                • M mpergand

                  @AntonBogun said in Widget doesn't take the whole vertical space:

                  Is it possible to somehow add "another" layout on top of what MainWindow does, and have it draw over what MainWindow draws? I get the impression of the QWidget::setLayout() that it is not the case,

                  You can add a layout to a QBoxLayout:
                  void QBoxLayout::addLayout(QLayout *layout, int stretch = 0)

                  A Offline
                  A Offline
                  AntonBogun
                  wrote on last edited by AntonBogun
                  #7

                  @mpergand said in Widget doesn't take the whole vertical space:

                  @AntonBogun said in Widget doesn't take the whole vertical space:

                  Is it possible to somehow add "another" layout on top of what MainWindow does, and have it draw over what MainWindow draws? I get the impression of the QWidget::setLayout() that it is not the case,

                  You can add a layout to a QBoxLayout:
                  void QBoxLayout::addLayout(QLayout *layout, int stretch = 0)

                  From what I've tested, adding child layouts to other layouts does not in fact allow them to overlap and have one of them draw on top of the other.

                  Also, I actually managed to solve it by thinking about it some more and tweaking it until it started working:

                  //notificationwidget.h
                  NotificationWidget::NotificationWidget(QWidget *parent) 
                      : QScrollArea(parent),
                        m_scrollWidget(new QWidget), 
                        m_scrollLayout(new QVBoxLayout(m_scrollWidget)) 
                  {
                      setWidget(m_scrollWidget);
                      setWidgetResizable(true);
                      setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
                  
                      m_scrollWidget->setLayout(m_scrollLayout);
                  
                      setFixedWidth(qMin(300, parentWidget()->width() *4/5));
                      setMaximumHeight(0.6*parentWidget()->height());
                  }
                  QSize NotificationWidget::sizeHint() const {
                      return m_scrollWidget->sizeHint()+QSize(0,2); // without +2 scroll bar appears
                  }
                  
                  void NotificationWidget::addNotification(const QString &message) {
                      QLabel *label = new QLabel(message, this);
                      label->setWordWrap(true);
                      m_scrollLayout->addWidget(label);
                      m_scrollWidget->adjustSize();
                      adjustSize();
                  }
                  
                  void NotificationWidget::resizeEvent(QResizeEvent *event) {
                      QWidget::resizeEvent(event);
                      setFixedWidth(qMin(300, parentWidget()->width() *4/5));
                      setMaximumHeight(0.6*parentWidget()->height());
                      m_scrollWidget->adjustSize();//necessary
                      adjustSize();
                  }
                  
                  //mainwindow.cpp
                  void MainWindow::updateNotificationWidgetPosition() {
                      m_notificationWidget->setFixedWidth(qMin(300, width() *4/5));
                      m_notificationWidget->setMaximumHeight(height());
                      m_notificationWidget->adjustSize();//necessary
                      int newX = width() - m_notificationWidget->width() - 0.03 * width();
                      int newY = height() - m_notificationWidget->height() - 0.03 * height();
                      m_notificationWidget->move(newX, newY);
                  }
                  

                  Everyone so far seems to have missed the point that this should overlap and draw over the existing contents of the mainwindow, and afaik you can't do that with a layout.
                  The gif of the final result, notice specifically how the goal is for the NotificationWidget to overlap over other contents.

                  I still wonder if there is some less hacky way to do this though. And possibly it could break in some edge cases which I'm unaware of.
                  I'll leave this open for a bit so that maybe someone can post a better solution to get this behaviour.

                  1 Reply Last reply
                  0
                  • JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by
                    #8

                    @AntonBogun said in Widget doesn't take the whole vertical space:

                    Also, I actually managed to solve it by thinking about it some more and tweaking it until it started working:

                    The best way I know of figuring what's going on with widgets/layouts :)

                    Everyone so far seems to have missed the point that this should overlap and draw over the existing contents of the mainwindow, and afaik you can't do that with a layout.

                    I did wonder if that was what you wanted but wasn't sure. If you want to position something "absolutely" and not go with the flow of other widgets on layouts then you should indeed take it outside a layout and use absolute positioning.

                    1 Reply Last reply
                    0
                    • A AntonBogun has marked this topic as solved on
                    • A AntonBogun referenced this topic on

                    • Login

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