1 year ago

#64399

test-img

hehe HE

When I use Qt6 and draw a pixmap on a QWidget however in some conditions the pixmap will disappear

I use Visual Studio 2022 to write a Qt demo to show a icon of an image in my Qt application. To make sure QPainter::Antialiasing enable, I write a derived class from QWidget instead of using QLabel, and rewrite the void paintEvent(QPaintEvent *) to achieve my goal.

It worked, but something is wrong.

I set the maximumsize and minimumsize of MyWidget in my .ui file. When the window's width is max and height is minimum, the pixmap will disappear. Just like these:

normal situation

It looks good. However, then make the height minimum:

the pixmap disappears

And this is the class I have written:

#pragma once

#include <QWidget>
#include <QPixmap>

class IconWidget : public QWidget {
    Q_OBJECT

public:
    IconWidget(QWidget *parent);
    ~IconWidget();

private:
    QPixmap m_pixmap;
    bool m_pixmapChanged;
    QSize m_oldWidgetSize;

protected:
    void paintEvent(QPaintEvent *) override;

public:
    void setPixmap(const QPixmap &pixmap);
    void setPixmap(const QString &pixmapPath);
};

#include <QPainter>

IconWidget::IconWidget(QWidget *parent)
    : QWidget(parent), m_pixmapChanged(false) {}

IconWidget::~IconWidget() {}

void IconWidget::paintEvent(QPaintEvent *) {
    auto &&curSize = size();
    if (curSize == m_oldWidgetSize && !m_pixmapChanged)
        return;

    auto [pixw, pixh] = m_pixmap.size();
    auto [widw, widh] = this->size();
    qreal scaleRate = std::min((qreal)widw / pixw, (qreal)widh / pixh);
    pixw = std::min(widw, (int)(pixw * scaleRate));
    pixh = std::min(widh, (int)(pixh * scaleRate));

    QRect renderRect((widw - pixw) / 2, widh - pixh, pixw, pixh);
    QPainter painter(this);

    painter.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing);
    painter.drawPixmap(renderRect, m_pixmap);

    m_pixmapChanged = false;
    m_oldWidgetSize = curSize;
}

void IconWidget::setPixmap(const QPixmap &pixmap) {
    m_pixmap = pixmap.scaled(maximumSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
    m_pixmapChanged = true;
}

void IconWidget::setPixmap(const QString &pixmapPath) {
    m_pixmap = QPixmap(pixmapPath).scaled(maximumSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
    m_pixmapChanged = true;
}

I try to add a dely to the paintEvent:

void IconWidget::paintEvent(QPaintEvent *) {
    Sleep(10);
    auto &&curSize = size();
    if (curSize == m_oldWidgetSize && !m_pixmapChanged)
        return;

    auto [pixw, pixh] = m_pixmap.size();
    auto [widw, widh] = this->size();
    qreal scaleRate = min((qreal)widw / pixw, (qreal)widh / pixh);
    pixw = min(widw, (int)(pixw * scaleRate));
    pixh = min(widh, (int)(pixh * scaleRate));

    QRect renderRect((widw - pixw) / 2, widh - pixh, pixw, pixh);
    QPainter painter(this);

    painter.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing);
    painter.drawPixmap(renderRect, m_pixmap);

    m_pixmapChanged = false;
    m_oldWidgetSize = curSize;
}

The problem isn't solved.

So what happened to my code? And how can I fix it?

c++

qt

qpainter

qpixmap

qt6

0 Answers

Your Answer

Accepted video resources