问题:
在设置了以下代码后,图片在高分辨率下显示的挺好
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
但是在paintEvent里绘制图片,不管是drawImage还是drawPixmap效果都不是很好
解决方案:
比如在1080p上你要显示32x32的图片,那么在2K上准备一个64x64的图片
QPainter painter(this);
painter.setRenderHint(QPainter::HighQualityAntialiasing);
QPixmap pixmap = icon().pixmap(iconSize());
qreal pixelRatio = painter.device()->devicePixelRatioF();
pixmap = pixmap.scaled(QSize(iconSize().width() * pixelRatio, iconSize().height() * pixelRatio), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
QPainter icon(&pixmap);
icon.setCompositionMode(QPainter::CompositionMode_SourceIn);
icon.fillRect(pixmap.rect(), isEnabled() ? color() : disabledColor());
const qreal w = iconSize().width();
const qreal h = iconSize().height();
painter.drawPixmap(QRect((rect().width() - w) / 2, (rect().height() - h) / 2, w, h), pixmap);
我们加载的pixmap原大小是64x64的, 在1080p上一下代码可以很好的转换成32x32的
pixmap = pixmap.scaled(QSize(32, 32), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
但是在2K屏幕上,一样的代码会模糊。
所以先获取当前设备的pixelRatio
//下面两行代码是解决问题的关键
qreal pixelRatio = painter.device()->devicePixelRatioF();
转换时,用你要装换的大小乘以这个系数,如下
pixmap = pixmap.scaled(QSize(iconSize().width() * pixelRatio, iconSize().height() *
pixelRatio), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
这时pixmap的大小不一定是32x32了,但是我们drawPixmap的时候一定把他当做32x32的rect就好了,注意,这里不要填pixmap.rect();而是你想要转换的没乘以系数的那个rect,比如pushbtn.rect();
painter.drawPixmap(0, 0, w, h), pixmap);
到此问题解决
延伸,在没设置凯文那两行代码前,可以使用下面的代码获取文本缩放比率
float MiFramelessWindow::getTextScaled()
{
double rate = 0;
QList<QScreen *> screens = QApplication::screens();
if (screens.size() > 0) {
double dpi = this->screen()->logicalDotsPerInch();
rate = dpi / 96.0;
if (rate < 1.1) {
rate = 1.0;
}
else if (rate < 1.4) {
rate = 1.25;
}
else if (rate < 1.6) {
rate = 1.5;
}
else if (rate < 1.8) {
rate = 1.75;
}
else {
rate = 2.0;
}
}
return rate;
}