2 つの笑顔を描くアプリケーションを作成しました。
最初のものは QWidget に直接描画されます:
void DirectFace::paintEvent(QPaintEvent *ev)
{
QPainter painter(this);
paintFace(painter);
}
2 つ目は にペイントされ、QPixmap
次にウィジェットにブリットされます。
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
アプリを設定して実行します。
最初の顔はシャープで鮮明ですが、2 番目の顔はピクセル化されています。これは、低解像度のピックスマップに描画されているためです。だから私はそれを拡大し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());
}
結果:
2 番目の顔は、正しい解像度で描画されているように見えますが、アップスケールされています。今、私は立ち往生しています。Retina/HiDPI画面で正しく動作するようにQPixmap
描画してから描画する方法は?QPixmap
アプリケーション全体:
#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();
}