Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to maintain QWidget aspect ratio?



  • Re: [Solved] How to Preserve the aspect ratio of a widget?

    The referenced article says somebody solved it but no mention on how it is done, and the tutorial links don't exist anymore. Would be nice to see some actual "complete" code that works. I just want my widget to stay "square". Just for kicks, I overrode heightForWidth and even hasHeightForWidth in my custom widget but no luck.

    I'm using a basic form, QMainWindow with a central widget laying out vertically, my custom widget sits in the central widget. I want it to remain square no matter what size the QMainWindow is resized to.



  • There is no build in function for the aspect ratio behavior.
    However you can do something like this:

    class AspectRatioWidget : public QWidget
    {
        Q_OBJECT
    public:
        AspectRatioWidget(QWidget *parent = 0);
    
       // the widget we want to keep the ratio
        void setAspectWidget(QWidget* widget, const double ratio = 1.0);
        void setRatio(const double ratio);
    
    protected:
        void resizeEvent(QResizeEvent *event);
    
    public slots:
        void applyAspectRatio();
    
    private:
        QHBoxLayout* m_layout;
    
        QWidget* m_aspect_widget;
    
        double m_ratio;
    };
    
    AspectRatioWidget::AspectRatioWidget(QWidget *parent):
        QWidget(parent)
    {
        m_layout = new QHBoxLayout();
        m_layout->setSpacing(0);
        m_layout->setContentsMargins(0, 0, 0, 0);
        setLayout(m_layout);
    }
    
    void AspectRatioWidget::setRatio(const double ratio)
    {
        m_ratio = ratio;
        applyAspectRatio();
    }
    
    void AspectRatioWidget::setAspectWidget(QWidget *widget, const double ratio)
    {
        m_aspect_widget = widget;
        m_layout->addWidget(widget);
        m_ratio = ratio;
    }
    
    void AspectRatioWidget::resizeEvent(QResizeEvent *event)
    {
        (void)event;
        applyAspectRatio();
    }
    
    
    void AspectRatioWidget::applyAspectRatio()
    {
        int w = this->width();
        int h = this->height();
        double aspect = static_cast<double>(h)/static_cast<double>(w);
    
        if(aspect < m_ratio) // parent is too wide
        {
            int target_width = static_cast<int>(static_cast<double>(h)/m_ratio);
            m_aspect_widget->setMaximumWidth(target_width);
            m_aspect_widget->setMaximumHeight(h);
    
        }
        else // parent is too high
        {
            int target_heigth = static_cast<int>(static_cast<double>(w)*m_ratio);
            m_aspect_widget->setMaximumHeight(target_heigth);
            m_aspect_widget->setMaximumWidth(w);
        }
    }
    

Log in to reply