我写了两个笑脸的应用程序:
第一个直接在QWidget上绘制:
void DirectFace::paintEvent(QPaintEvent *ev)
{
QPainter painter(this);
paintFace(painter);
}
第二个被绘制在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
到目前为止一切顺利。我想看看我的应用在高分辨率屏幕上的外观(我没有),所以我设置QPixmap
并运行我的应用:
第一张脸是清晰而明快的,而seconf则是像素化的。这是因为它被低分辨率像素图所吸引。所以我放大了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
结果:
第二张脸看起来像是以正确的分辨率绘制,但随后放大了。现在我被卡住了。如何绘制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();
}
,以便它在Retina / HiDPI屏幕上正常工作?
整个申请:
Squib::Deck.new(cards: 6) do
答案 0 :(得分:2)
如果您想要HighDPI渲染,您还应该为QPainter函数使用QRectF和QPointF参数。在paintFace(...)函数中,调整drawEllipse和drawText函数以使用QRectF参数而不是QRect。这可能有所帮助。
使用qApp-&gt; devicePixelRatio()不是一个好主意。有些人使用混合的HighDPI和非HighDPI监视器。当你在一个小部件paintEvent(...)函数中,你可以直接使用QWidget成员函数devicePixelRatioF(),而不是qApp-&gt; devicePixelRatio()。这将处理小部件的正确呈现,即使用户在具有混合分辨率的监视器之间移动小部件也是如此。
您还应该通过QtoreApplication :: setAttribute(Qt :: AA_EnableHighDpiScaling)启用Qt中的高DPI缩放;
这里提供了完整的解决方案,即使在小部件之间移动时,也可以在HighDPI和Non-HighDPI屏幕上完美呈现笑脸。用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();
}