Qt:绘制高DPI QPixmaps

时间:2017-02-02 20:08:53

标签: c++ qt qpainter qpixmap highdpi

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

enter image description here

第一个直接在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并运行我的应用:

enter image description here

第一张脸是清晰而明快的,而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

结果:

enter image description here

第二张脸看起来像是以正确的分辨率绘制,但随后放大了。现在我被卡住了。如何绘制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

1 个答案:

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