Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. General talk
  3. Brainstorm
  4. Height for Width - Maintaining Aspect Ratio of a QWidget

Height for Width - Maintaining Aspect Ratio of a QWidget

Scheduled Pinned Locked Moved Solved Brainstorm
4 Posts 2 Posters 10.9k 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.
  • D Offline
    D Offline
    Drakkhan
    wrote on last edited by Drakkhan
    #1

    Hi everyone, I'm new here, hope this is in the right section.

    Looking for some expert help. I've been googling all afternoon. It seems like there used to be a solution for this question, but the links are dead.

    I want to have a widget within a set of nested layouts maintain a square aspect ratio. I've created a simple "main.cpp" to illustrate my problem.

    The following code is my best stab at getting QWidget "theWidget" to stay square, but it doesn't:

    #include <QApplication>
    
    #include <QPushButton>
    #include <QApplication>
    #include <QLayout>
    #include <QSizePolicy>
    #include <QLabel>
    
    int main(int argc, char **argv)
    {
     QApplication app (argc, argv);
    
     //Create Primary Widget
     QWidget *window = new QWidget;
     window->setMinimumSize(100, 100);
    
     // Create Secondary Widget that SHOULD be Square
     QLabel *theWidget = new QLabel("Hello World!", window);
     QSizePolicy thePolicy = QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
     QHBoxLayout *theLayout = new QHBoxLayout;
    
     // Format Secondary Widget
     theWidget->setFrameStyle(QFrame::Panel | QFrame::Raised);
     theWidget->setLineWidth(2);
     theWidget->setAlignment(Qt::AlignCenter | Qt::AlignCenter);
     theWidget->setMinimumSize(100, 100);
    
     // Attempt to Square Secondary Widget
     thePolicy.setHeightForWidth(true);
     theWidget->setSizePolicy(thePolicy);
    
     // Add Secondary Widget to a Layout
     theLayout->addWidget(theWidget);
    
     // Set the Primary Widget to have the Layout.
     window->setLayout(theLayout);
     window->show();
    
     return app.exec();
    }
    
    1 Reply Last reply
    0
    • J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #2

      Hi, sadly, the setHeightForWidth property only works in a QGraphicsLayout that got changed a while ago.

      Since that change, I don't know of an inbuild way to force a square Aspect Ratio of a widget in a normal QLayout, accept rewriting the ResizeEvent

      protected:
          virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
      
      ...
      
      void resizeEvent(QResizeEvent *event)
      {
          event->accept();
      
          if(event->size().width() > event->size().height()){
              QWidget::resize(event->size().height(),event->size().height());
          }else{
              QWidget::resize(event->size().width(),event->size().width());
          }
      }
      
      

      Maybe someone else has a better solution.


      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.

      D 1 Reply Last reply
      3
      • J.HilkJ J.Hilk

        Hi, sadly, the setHeightForWidth property only works in a QGraphicsLayout that got changed a while ago.

        Since that change, I don't know of an inbuild way to force a square Aspect Ratio of a widget in a normal QLayout, accept rewriting the ResizeEvent

        protected:
            virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
        
        ...
        
        void resizeEvent(QResizeEvent *event)
        {
            event->accept();
        
            if(event->size().width() > event->size().height()){
                QWidget::resize(event->size().height(),event->size().height());
            }else{
                QWidget::resize(event->size().width(),event->size().width());
            }
        }
        
        

        Maybe someone else has a better solution.

        D Offline
        D Offline
        Drakkhan
        wrote on last edited by Drakkhan
        #3

        @J.Hilk Thanks very much. This did the trick! Not sure what sort of pitfalls are in store for reimplementing resizeEvent, but I haven't found any yet!

        I will post back here if I find a problem. :)

        My Adjustment to Your Solution:

        mycustomwidget.h:

        #ifndef MYCUSTOMWIDGET_H
        #define MYCUSTOMWIDGET_H
        
        #include <QWidget>
        #include <QResizeEvent>
        
        class MyCustomWidget : public QWidget
        {
             Q_OBJECT
        public:
             explicit MyCustomWIdget(QWidget *parent=0);
        
        protected:
             virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
        };
        
        #endif // MYCUSTOMWIDGET_H
        

        mycustomwidget.cpp:

        MyCustomWidget::MyCustomWidget(QWidget *parent) : QWidget(parent)
        {
             // Implementation doesn't pertain to this example...
        }
        
        void MyCustomWidget::resizeEvent(QResizeEvent *event)
        {
            event->accept();
        
            if(event->size().width() > event->size().height()){
                QWidget::resize(event->size().height(),event->size().height());
            }else{
                QWidget::resize(event->size().width(),event->size().width());
            }
        }
        

        Thanks again!

        J.HilkJ 1 Reply Last reply
        0
        • D Drakkhan

          @J.Hilk Thanks very much. This did the trick! Not sure what sort of pitfalls are in store for reimplementing resizeEvent, but I haven't found any yet!

          I will post back here if I find a problem. :)

          My Adjustment to Your Solution:

          mycustomwidget.h:

          #ifndef MYCUSTOMWIDGET_H
          #define MYCUSTOMWIDGET_H
          
          #include <QWidget>
          #include <QResizeEvent>
          
          class MyCustomWidget : public QWidget
          {
               Q_OBJECT
          public:
               explicit MyCustomWIdget(QWidget *parent=0);
          
          protected:
               virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
          };
          
          #endif // MYCUSTOMWIDGET_H
          

          mycustomwidget.cpp:

          MyCustomWidget::MyCustomWidget(QWidget *parent) : QWidget(parent)
          {
               // Implementation doesn't pertain to this example...
          }
          
          void MyCustomWidget::resizeEvent(QResizeEvent *event)
          {
              event->accept();
          
              if(event->size().width() > event->size().height()){
                  QWidget::resize(event->size().height(),event->size().height());
              }else{
                  QWidget::resize(event->size().width(),event->size().width());
              }
          }
          

          Thanks again!

          J.HilkJ Offline
          J.HilkJ Offline
          J.Hilk
          Moderators
          wrote on last edited by
          #4

          @Drakkhan I should mention, that this resize in ResizeEvent can easily end in an recursive loop.
          This should be pretty safe, if it is a standalone window for example. But if you have to be careful, if you want to use it in QLayout. Those tend to be difficult.

          I would suggest either, subclassing and making your own QLayout Flow Layout Example or nesting your custom Widget inside an other one that is effected by the Layout, and handels the positioning of your custom -square- widget.

          I prefer the 2nd option myself.


          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.

          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