theIpatix
theIpatix

Reputation: 36

Qt: How to render SVG properly to QLabel without scaling?

I'm currently having a problem where I try to render an SVG file to a QLabel and it does not display correctly:

stop sign SVG displayed wrongly in main window

This is how the SVG actually looks like:

stop sign SVG

I want the SVG to be displayed without scaling (I mean, that's what SVG is all about, isn't it) in it's original square shape. The SVG has a size specified of 256x256, but I don't care about that as long as it fills the layout's cell and it's displayed in its correct aspect ratio.

This is the meaningful part of the header:

class LoginUnavailableWindow : public QWidget {
    Q_OBJECT
public:
    explicit LoginUnavailableWindow(QWidget *parent = nullptr);
    ~LoginUnavailableWindow() override;
private:
    QHBoxLayout errorLayout {this};
    QLabel errorIconLabel {this};
    QLabel errorTextLabel {this};
};

And this is the meaningful part of the main cpp:

LoginUnavailableWindow::LoginUnavailableWindow(QWidget *parent) : QWidget(parent) {
    /* set overall layout */
    errorLayout.addWidget(&errorIconLabel);
    errorLayout.addWidget(&errorTextLabel);
    errorLayout.setStretch(0, 1);
    errorLayout.setStretch(1, 3);

    /* apply size constraints */
    setMinimumSize(800, 200);
    setMaximumSize(800, 200);
    errorTextLabel.setAlignment(Qt::AlignCenter);
    errorIconLabel.setAlignment(Qt::AlignCenter);

    /* set text */
    QFont font = errorTextLabel.font();
    font.setPointSize(48);
    errorTextLabel.setFont(font);
    errorTextLabel.setText("Login is currently\nunavailable");

    /* render SVG */
    QSvgRenderer renderer(ERROR_SVG_PATH);
    QPixmap pm(errorIconLabel.size());
    pm.fill(QColorConstants::Transparent);
    QPainter painter(&pm);
    renderer.render(&painter, pm.rect());
    errorIconLabel.setPixmap(pm);
}

The actual SVG rendering code was taken from here. One of the problems that I can see is that errorIconLabel.size() is returning 100x30 which I find very confusing. How do I get the actual size of the layouts cell so that I can calculate at which resolution to render the SVG?

A lot of answers I found would use setScaledContents() which does cause the pixmap to be displayed at a more reasonable size, but then it's all blurry/pixelated since the SVG is still rendered at the wrong resolution. I would like to achieve this without introducing scaling artifacts.

Upvotes: 0

Views: 733

Answers (1)

theIpatix
theIpatix

Reputation: 36

Okay, I was able to solve this on my own. I've realized that the QLabel would only have the size 100x30 returned in the constructor. After the constructor finishes, a resizeEvent is issued directly and inside this resizeEvent the size of that label is returned correctly.

So my solution in the end was to implement void resizeEvent(QResizeEvent *) override in LoginUnavailableWindow and to always redraw the SVG when the size would change. In my case I force the window size fixed, but if someone else would do this, it would also solve display problems when the user would resize the window.

Upvotes: 1

Related Questions