Height for Width - Maintaining Aspect Ratio of a QWidget



  • 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();
    }
    


  • 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.



  • @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!



  • @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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.