我编写了一个绘制两个笑脸的应用程序:
第一个是直接绘制在QWidget上的:
void DirectFace::paintEvent(QPaintEvent *ev)
{
QPainter painter(this);
paintFace(painter);
}
第二个是画在 QPixmap
上,然后将其 blit 到小部件上:
void BufferedFace::paintEvent(QPaintEvent *ev)
{
QPixmap buffer(width(), height());
buffer.fill(Qt::transparent);
QPainter painter(&buffer);
paintFace(painter);
QPainter p(this);
p.drawPixmap(ev->rect(), buffer, ev->rect());
}
目前为止都很好。我想看看我的应用程序在高分辨率屏幕上的效果(我没有这样的屏幕),所以我设置了QT_SCALE_FACTOR=2
,然后运行了我的应用程序:
第一张图片是清晰的,而第二张图片是有像素的。这是因为它被绘制到低分辨率的 pixmap 上。因此,我已经放大了那个 QPixmap
并设置了正确的 devicePixelRatio
:
void BufferedFace::paintEvent(QPaintEvent *ev)
{
qreal pixelRatio = qApp->devicePixelRatio();
QPixmap buffer(width() * pixelRatio, height() * pixelRatio);
buffer.setDevicePixelRatio(pixelRatio);
buffer.fill(Qt::transparent);
QPainter painter(&buffer);
paintFace(painter);
QPainter p(this);
p.drawPixmap(ev->rect(), buffer, ev->rect());
}
结果:
第二张图片看起来像是以正确的分辨率绘制,然后进行了放大。现在我卡住了。如何在 QPixmap
上绘制并将其绘制出来,以便在 Retina/HiDPI 屏幕上正常工作?
整个应用程序:
#include <QtWidgets>
class SmilingFace : public QWidget
{
public:
SmilingFace(QWidget *parent) : QWidget(parent) {};
void paintFace(QPainter &painter);
};
class DirectFace : public SmilingFace
{
public:
DirectFace(QWidget *parent) : SmilingFace(parent) {}
void paintEvent(QPaintEvent *ev) override;
};
class BufferedFace : public SmilingFace
{
public:
BufferedFace(QWidget *parent) : SmilingFace(parent) {}
void paintEvent(QPaintEvent *ev) override;
};
void SmilingFace::paintFace(QPainter &painter)
{
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(Qt::NoPen);
painter.setBrush(QBrush(Qt::lightGray));
painter.drawEllipse(1, 1, width()-2, height()-2);
painter.setPen(Qt::white);
painter.setFont(QFont("", 32));
painter.drawText(rect(), Qt::AlignHCenter, ";)");
}
void DirectFace::paintEvent(QPaintEvent *ev)
{
QPainter painter(this);
paintFace(painter);
}
void BufferedFace::paintEvent(QPaintEvent *ev)
{
QPixmap buffer(width(), height());
buffer.fill(Qt::transparent);
QPainter painter(&buffer);
paintFace(painter);
QPainter p(this);
p.drawPixmap(ev->rect(), buffer, ev->rect());
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
w.setWindowTitle("HiDPI");
DirectFace d(&w);
d.resize(48, 48);
d.move(16, 16);
BufferedFace i(&w);
i.resize(48, 48);
i.move(16 + 48 + 16, 16);
w.show();
return a.exec();
}