gpt4 book ai didi

c++ - Qt:绘制高 DPI QPixmaps

转载 作者:搜寻专家 更新时间:2023-10-31 02:12:58 24 4
gpt4 key购买 nike

我写了一个画了两个笑脸的应用程序:

enter image description here

第一个是直接在QWidget上画的:

void DirectFace::paintEvent(QPaintEvent *ev)
{
QPainter painter(this);
paintFace(painter);
}

第二个绘制在 QPixmap 上,然后被 blit 到 widget:

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 并运行我的应用程序:

enter image description here

第一张脸清晰锐利,而第二张脸像素化。那是因为它被绘制到低分辨率像素图。所以我扩大了 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());
}

结果:

enter image description here

第二张脸看起来是用正确的分辨率绘制的,但后来放大了。现在我卡住了。如何在 QPixmap 上绘制,然后绘制那个 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();
}

最佳答案

如果你想要 HighDPI 渲染,你还应该为 QPainter 函数使用 QRectF 和 QPointF 参数。在您的 paintFace(...) 函数中,调整 drawEllipse 和 drawText 函数以使用 QRectF 参数而不是 QRect。这可能会有所帮助。

使用 qApp->devicePixelRatio() 不是一个好主意。有些人混合使用 HighDPI 和非 HighDPI 显示器。当你在 widget paintEvent(...) 函数中时,你可以直接使用 QWidget 成员函数 devicePixelRatioF(),而不是 qApp->devicePixelRatio()。这将处理小部件的正确呈现,即使用户在具有混合分辨率的显示器之间移动小部件也是如此。

您还应该通过以下方式在 Qt 中启用高 DPI 缩放:QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

这是完整的解决方案,它可以在高 DPI 和非高 DPI 屏幕上完美呈现笑脸,即使小部件在两者之间移动也是如此。使用 Qt 5.9.2 测试

#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(QRectF(1, 1, width() - 2, height() - 2));

painter.setPen(Qt::white);
painter.setFont(QFont("", 32));
painter.drawText(QRectF(0, 0, width(), height()), Qt::AlignHCenter, ";)");
}

void DirectFace::paintEvent(QPaintEvent *ev)
{
QPainter painter(this);
paintFace(painter);
}

void BufferedFace::paintEvent(QPaintEvent *ev)
{
qreal dpr = devicePixelRatioF();
QPixmap buffer(width() * dpr, height() * dpr);
buffer.setDevicePixelRatio(dpr);
buffer.fill(Qt::transparent);
QPainter painter(&buffer);
paintFace(painter);

QPainter p(this);
p.drawPixmap(ev->rect(), buffer, buffer.rect());
}

int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

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();
}

关于c++ - Qt:绘制高 DPI QPixmaps,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42011410/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com