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

image on QWidget resize and keep aspect ratio



  • Hi,

    I see this question over and over, and now I it is my time: is thre some type of QWidget with click slot, that displays an image, and when the widget resizes, so does the image, but the image keeps its aspect ratio, I mean, if it is a circle, it stays a circle, never becoming an ellipse?

    I read http://doc.qt.io/qt-4.8/stylesheet-customizing.html#box-model, https://stackoverflow.com/questions/32111438/qpushbutton-icon-maximize-on-resize-event and https://forum.qt.io/topic/7978/icon-in-pushbutton-does-not-resize/5, but I was not able to implement the suggestion in the last two URLs, as the code I wrote caused the resize event to be called forever.

    I wrote an algorithm that (I think) calculates the sizes of the image, based on the new size of the widget, in order to keep the aspect ratio. But it would go in the resizeEvent method, that, in my experience, as I said above, caused the resize event to be called repeatedly.

    Is there a good solution for this, or even a property in QPushButton (or any other widget), that I am not aware of?

    Thanks a lot!


  • Moderators

    @canellas
    a solution via the resize-event is never correct, since a layout is most probably responsible for the size.
    The most universal approach would be to do the painting of the image (best-fit) yourself. Independant of the actual widget size ratio.

    Or you can try to do the following (untested):

    MyWidget::MyWidget()
    {
         QSizePolicy sp = this->sizePolicy();
             sp.setHorizontalPolicy( QSizePolicy::Preferred );
             sp.setVerticalPolicy( QSizePolicy::Preferred );
             sp.setHeightForWidth( true );
         this->setSizePolicy( sp );
    }
    
    int MyWidget::heightForWidth( int width )
    {
        if( this->layout() )
             return BaseClass::heightForWidth( width );
        int width = ...; // calculate the width based on the height in same aspect ratio of the image
        return width;
    }
    


  • @raven-worx said in image on QWidget resize and keep aspect ratio:

    @canellas
    a solution via the resize-event is never correct, since a layout is most probably responsible for the size.
    The most universal approach would be to do the painting of the image (best-fit) yourself. Independant of the actual widget size ratio.

    Or you can try to do the following (untested):

    MyWidget::MyWidget()
    {
         QSizePolicy sp = this->sizePolicy();
             sp.setHorizontalPolicy( QSizePolicy::Preferred );
             sp.setVerticalPolicy( QSizePolicy::Preferred );
             sp.setHeightForWidth( true );
         this->setSizePolicy( sp );
    }
    
    int MyWidget::heightForWidth( int width )
    {
        if( this->layout() )
             return BaseClass::heightForWidth( width );
        int width = ...; // calculate the width based on the height in same aspect ratio of the image
        return width;
    }
    

    This solved my problem. I almost spent whole 1 day to implement this but nothing helped. I overrode resizeEvent, sizeHint, minimumSizeHint and called functions like resize but nothing worked. Either height of widget didn't change or layout didn't resize itself when widget height changed.

    It shouldn't be hard for an image fill entire widget. Also it is too hard to extract this information from documentation.


Log in to reply