Siyuan Ren
Siyuan Ren

Reputation: 7844

How to properly use adjustSize() in Qt

I'm new to Qt, and this issue about auto resizing has driven me crazy.

I create a class called RenderArea that inherits QWidget. In its paintEvent(), I use a QPainter to draw an image. In order for the whole window to scale with the image, I resize before painting. The relevant code is

if (image && !image->isNull())
{
    resize(image->size());
    painter.drawImage(image->rect(), *image, image->rect());
}

However, RenderArea will stretch too much through other widgets (like buttons and menus). It is contained in a centralWidget with a vertical layout. But when I call centralWidget->adjustSize() it does not scale everything together, but instead shrinks RenderArea t and hides the image.

How do I instruct the central widget as well as the window to scale with the new size of my customized widget? I know I could use a QLabel and set its scaledContents to be true, but I need a lot of other sophisticated rendering so a simple QLabel is not enough.

Upvotes: 4

Views: 14126

Answers (1)

fasked
fasked

Reputation: 3645

The sizeHint function should return recommended widget's size. So RenderArea should return image size as its sizeHint. When the image is changed the updateGeometry function should be called to update a cached sizeHint value:

class RenderArea : public QWidget 
{
public:
    explicit RenderArea(const QImage &image, QWidget *parent = 0) 
        : QWidget(parent), m_image(image)
    {
    }

    QSize sizeHint() const 
    {
        return m_image.isNull() ? QWidget::sizeHint() : m_image.size();
    }

    void paintEvent(QPaintEvent *event)
    {
        QWidget::paintEvent(event);
        if (!m_image.isNull())
        {
            QPainter painter(this);
            painter.drawImage(rect(), m_image, m_image.rect());
        }
    }

    void setImage(const QImage &image)
    {
        m_image = image;
        updateGeometry();
    }

private:
    QImage m_image;
};

When the child widget is resized, the parent widget isn't doing it automatically. Fortunately there is QWidget::adjustSize function which lets us to resize the parent widget to fit its content:

class Window : public QWidget 
{
    Q_OBJECT

private slots:
    void onImageChanged(const QString &fileName)
    {
        m_area->setImage(QImage(fileName));
        adjustSize();
    }

private:
    RenderArea *m_area;
};

Upvotes: 7

Related Questions