You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt6中DPI设为125%时QLabel内QPixmap显示模糊问题

问题描述

我正在使用Qt6,通过QPixmap在QLabel中绘制一张PNG图片,并将像素图调整至适配QLabel的尺寸。当DPI设置为100%时,显示效果正常;但在笔记本电脑(默认推荐DPI为125%,用于放大文字)上,像素图显示模糊(线条发虚)。

相比之下,将同一张PNG图片设置为QPushButton的图标时,显示效果却正常。

请问我哪里操作有误?如何修改代码才能让QLabel中的图片显示效果与QPushButton中的一样清晰?

完整代码

mainwindow.cpp

#include "mainwindow.h"

#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QApplication>
#include <QLabel>

MainWindow::MainWindow( QWidget* parent ) : QMainWindow(parent)
{
    QWidget* centralWidget = new QWidget(this);
    centralWidget->setLayout(new QVBoxLayout(centralWidget));

    QPushButton* button = new QPushButton(centralWidget);
    button->setIcon(QIcon(":/qtbug_pixmapscale/image.png"));

    QWidget* labelsWidget = new QWidget(centralWidget);
    labelsWidget->setLayout(new QHBoxLayout(labelsWidget));

    QLabel* titleLabel = new QLabel(centralWidget);
    titleLabel->setText("This is ugly:");

    QLabel* iconLabel = new QLabel(centralWidget);
    int maxHeight = titleLabel->sizeHint().height() + 10;
    iconLabel->setMaximumSize( QSize(maxHeight,maxHeight) );
    iconLabel->setPixmap(QPixmap(":/qtbug_pixmapscale/image.png").scaled(iconLabel->maximumSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
    
    labelsWidget->layout()->addWidget(titleLabel);
    labelsWidget->layout()->addWidget(iconLabel);

    centralWidget->layout()->addWidget(button);
    centralWidget->layout()->addWidget(labelsWidget);

    setCentralWidget(centralWidget);
}

main.cpp

#include <QApplication>
#include "mainwindow.h"

// Qtbug where QPixmap drawn in a QLabel looks ugly on laptop when display is set to 125%

int main( int argc, char* argv[] )
{
    QApplication app(argc, argv);

    MainWindow wnd; 
    wnd.show();

    return app.exec();
}

mainwindow.h

#pragma once

#include <QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget* parent = NULL);

};

pixmapscale.qrc

<RCC>
    <qresource prefix="/qtbug_pixmapscale">
        <file>image.png</file>
    </qresource>
</RCC>

(注:image.png为带线条的图标,在高DPI下QLabel显示模糊)


问题原因及解决方法

原因分析

问题出在直接使用设备无关的逻辑像素尺寸(widget的maximumSize)缩放QPixmap,未考虑Qt的高DPI缩放因子。QPushButton的setIcon会自动根据当前屏幕的设备像素比(DPR)处理图标,而手动调用scaled时用的是widget的逻辑像素尺寸,未转换为实际物理像素尺寸,导致缩放后的像素图分辨率不足,在高DPI屏幕上被拉伸后出现模糊。

解决方法

有两种可靠的修复方式:

方法一:手动处理设备像素比

在缩放QPixmap时,先获取屏幕的设备像素比,将逻辑尺寸转换为物理像素尺寸后再缩放:

QLabel* iconLabel = new QLabel(centralWidget);
int maxHeight = titleLabel->sizeHint().height() + 10;
iconLabel->setMaximumSize( QSize(maxHeight,maxHeight) );

// 获取当前屏幕的设备像素比
qreal dpr = qApp->primaryScreen()->devicePixelRatio();
// 将逻辑尺寸转换为物理像素尺寸
QSize actualSize = iconLabel->maximumSize() * dpr;

// 按物理像素尺寸缩放,并设置设备像素比
QPixmap pixmap(":/qtbug_pixmapscale/image.png");
pixmap = pixmap.scaled(actualSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
pixmap.setDevicePixelRatio(dpr);
iconLabel->setPixmap(pixmap);

方法二:让QLabel自动处理缩放(推荐)

无需手动缩放QPixmap,开启QLabel的scaledContents属性,让其自动根据自身尺寸和DPI适配图片:

QLabel* iconLabel = new QLabel(centralWidget);
int maxHeight = titleLabel->sizeHint().height() + 10;
iconLabel->setMaximumSize( QSize(maxHeight,maxHeight) );
// 开启自动缩放适配
iconLabel->setScaledContents(true);
// 直接设置原始QPixmap,QLabel会自动处理高DPI缩放
iconLabel->setPixmap(QPixmap(":/qtbug_pixmapscale/image.png"));

这种方法更简洁,效果与QPushButton的图标显示逻辑一致。

额外说明

  • Qt6默认启用高DPI支持,但手动操作QPixmap时需区分逻辑像素(widget使用的尺寸)和物理像素(屏幕实际像素点),两者的比值即为设备像素比(DPR)。
  • QIcon内部会自动管理不同DPI下的资源适配,而QPixmap需要手动处理DPR才能保证高DPI清晰度。

内容的提问来源于stack exchange,提问作者jpo38

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 06:37:04